From: Ahson Ahmed Khan Date: Fri, 10 Feb 2017 00:34:27 +0000 (-0800) Subject: Optimize Span.Fill (dotnet/coreclr#9441) X-Git-Tag: submit/tizen/20210909.063632~11030^2~8139 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=284040a105309bbccf5ccef244b8e0090035398a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Optimize Span.Fill (dotnet/coreclr#9441) Commit migrated from https://github.com/dotnet/coreclr/commit/1e76ef05c028be15bb79eb98f2a379b3746f3445 --- diff --git a/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs index b212f45..adfa015 100644 --- a/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -76,5 +76,18 @@ namespace System.Runtime.CompilerServices // See getILIntrinsicImplementationForUnsafe for how this happens. throw new InvalidOperationException(); } + + /// + /// Initializes a block of memory at the given location with a given initial value + /// without assuming architecture dependent alignment of the address. + /// + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) + { + // The body of this function will be replaced by the EE with unsafe code!!! + // See getILIntrinsicImplementationForUnsafe for how this happens. + throw new InvalidOperationException(); + } } } diff --git a/src/coreclr/src/mscorlib/src/System/Span.cs b/src/coreclr/src/mscorlib/src/System/Span.cs index 16467c3..c77a199 100644 --- a/src/coreclr/src/mscorlib/src/System/Span.cs +++ b/src/coreclr/src/mscorlib/src/System/Span.cs @@ -231,6 +231,7 @@ namespace System /// /// Clears the contents of this span. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clear() { // TODO: Optimize - https://github.com/dotnet/coreclr/issues/9161 @@ -245,10 +246,48 @@ namespace System /// public void Fill(T value) { - // TODO: Optimize - https://github.com/dotnet/coreclr/issues/9161 - for (int i = 0; i < _length; i++) + int length = _length; + + if (length == 0) + return; + + if (Unsafe.SizeOf() == 1) + { + byte fill = Unsafe.As(ref value); + ref byte r = ref Unsafe.As(ref _pointer.Value); + Unsafe.InitBlockUnaligned(ref r, fill, (uint)length); + } + else { - this[i] = value; + ref T r = ref DangerousGetPinnableReference(); + + // TODO: Create block fill for value types of power of two sizes e.g. 2,4,8,16 + + // Simple loop unrolling + int i = 0; + for (; i < (length & ~7); i += 8) + { + Unsafe.Add(ref r, i + 0) = value; + Unsafe.Add(ref r, i + 1) = value; + Unsafe.Add(ref r, i + 2) = value; + Unsafe.Add(ref r, i + 3) = value; + Unsafe.Add(ref r, i + 4) = value; + Unsafe.Add(ref r, i + 5) = value; + Unsafe.Add(ref r, i + 6) = value; + Unsafe.Add(ref r, i + 7) = value; + } + if (i < (length & ~3)) + { + Unsafe.Add(ref r, i + 0) = value; + Unsafe.Add(ref r, i + 1) = value; + Unsafe.Add(ref r, i + 2) = value; + Unsafe.Add(ref r, i + 3) = value; + i += 4; + } + for (; i < length; i++) + { + Unsafe.Add(ref r, i) = value; + } } } diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index d80b60e..5afb89b 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -7144,6 +7144,16 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_INIT_BLOCK_UNALIGNED)->GetMemberDef()) + { + static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 0x01, CEE_PREFIX1, (CEE_INITBLK & 0xFF), CEE_RET }; + methInfo->ILCode = const_cast(ilcode); + methInfo->ILCodeSize = sizeof(ilcode); + methInfo->maxStack = 3; + methInfo->EHcount = 0; + methInfo->options = (CorInfoOptions)0; + return true; + } return false; } diff --git a/src/coreclr/src/vm/mscorlib.h b/src/coreclr/src/vm/mscorlib.h index ca6b5e3..78eab6c 100644 --- a/src/coreclr/src/vm/mscorlib.h +++ b/src/coreclr/src/vm/mscorlib.h @@ -1205,6 +1205,7 @@ DEFINE_METHOD(UNSAFE, SIZEOF, SizeOf, NoSig) DEFINE_METHOD(UNSAFE, BYREF_AS, As, NoSig) DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, NoSig) DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig) +DEFINE_METHOD(UNSAFE, BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig) #endif DEFINE_CLASS(INTERLOCKED, Threading, Interlocked)