From 22e4c23d1e4ab65c0efcd94c28f791fcc78dcdc2 Mon Sep 17 00:00:00 2001 From: ahsonkhan Date: Fri, 24 Mar 2017 15:28:35 -0700 Subject: [PATCH 1/3] Fixing Span IndexOf vectorization. --- src/System.Memory/src/System/SpanHelpers.byte.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/System.Memory/src/System/SpanHelpers.byte.cs b/src/System.Memory/src/System/SpanHelpers.byte.cs index a702ffca5367..0d0e417a2fba 100644 --- a/src/System.Memory/src/System/SpanHelpers.byte.cs +++ b/src/System.Memory/src/System/SpanHelpers.byte.cs @@ -61,7 +61,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) unchecked { int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); - nLength = (IntPtr)(uint)unaligned; + nLength = (IntPtr)(uint)((Vector.Count - unaligned) % Vector.Count); } } SequentialScan: @@ -122,15 +122,16 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) { goto NotFound; } - nLength = (IntPtr)(uint)(length - Vector.Count); + nLength = (IntPtr)(uint)(length - (uint)index); // Get comparision Vector Vector vComparision = GetVector(value); - while ((byte*)nLength > (byte*)index) + while ((byte*)nLength >= (byte*)Vector.Count) { var vMatches = Vector.Equals(vComparision, Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, index))); if (Vector.Zero.Equals(vMatches)) { index += Vector.Count; + nLength -= Vector.Count; continue; } // Found match, reuse Vector vComparision to keep register pressure low @@ -139,7 +140,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) goto VectorFound; } - if ((int)(byte*)index > length) + if ((int)(byte*)index >= length) { goto NotFound; } From 4c51297701c9e317e604886bdfdc285955ef8f55 Mon Sep 17 00:00:00 2001 From: ahsonkhan Date: Fri, 24 Mar 2017 16:15:59 -0700 Subject: [PATCH 2/3] Addressing PR comments --- src/System.Memory/src/System/SpanHelpers.byte.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/System.Memory/src/System/SpanHelpers.byte.cs b/src/System.Memory/src/System/SpanHelpers.byte.cs index 0d0e417a2fba..082c55a2cce0 100644 --- a/src/System.Memory/src/System/SpanHelpers.byte.cs +++ b/src/System.Memory/src/System/SpanHelpers.byte.cs @@ -61,7 +61,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) unchecked { int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); - nLength = (IntPtr)(uint)((Vector.Count - unaligned) % Vector.Count); + nLength = (IntPtr)(uint)((Vector.Count - unaligned) & (Vector.Count - 1)); } } SequentialScan: @@ -122,16 +122,15 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) { goto NotFound; } - nLength = (IntPtr)(uint)(length - (uint)index); + nLength = (IntPtr)(uint)((length - (uint)index) & ~(Vector.Count - 1)); // Get comparision Vector Vector vComparision = GetVector(value); - while ((byte*)nLength >= (byte*)Vector.Count) + while ((byte*)nLength >= (byte*)index) { var vMatches = Vector.Equals(vComparision, Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, index))); if (Vector.Zero.Equals(vMatches)) { index += Vector.Count; - nLength -= Vector.Count; continue; } // Found match, reuse Vector vComparision to keep register pressure low From bae24f68c08f92ef2fb5594bbe475d038a2d3f45 Mon Sep 17 00:00:00 2001 From: ahsonkhan Date: Fri, 24 Mar 2017 17:02:19 -0700 Subject: [PATCH 3/3] Changing >= to > since we changed what nLength is. --- src/System.Memory/src/System/SpanHelpers.byte.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Memory/src/System/SpanHelpers.byte.cs b/src/System.Memory/src/System/SpanHelpers.byte.cs index 082c55a2cce0..fd007a0334e2 100644 --- a/src/System.Memory/src/System/SpanHelpers.byte.cs +++ b/src/System.Memory/src/System/SpanHelpers.byte.cs @@ -125,7 +125,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) nLength = (IntPtr)(uint)((length - (uint)index) & ~(Vector.Count - 1)); // Get comparision Vector Vector vComparision = GetVector(value); - while ((byte*)nLength >= (byte*)index) + while ((byte*)nLength > (byte*)index) { var vMatches = Vector.Equals(vComparision, Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, index))); if (Vector.Zero.Equals(vMatches))