4

In NetCore, MS added some new functions to copy memory, I want to know which is the best in performance.

Note: There is a similar answer for .NET Framework but NetCore has some drastical changes!

Cannot see any source code

  • Unsafe.CopyBlock - memcpy ?
  • Unsafe.CopyBlockUnaligned - will omit compiler check for aligned memory ?

These looks to be using same methods internally.

  • Array.Copy - user Buffer class.
  • Buffer.BlockCopy - .NET Framework used memcpy, using memmove in Core.
  • Buffer.MemoryCopy - docs suggest its using unsafe pointers to copy 64bit word per op, internally memmove.

I have used https://source.dot.net/ to inspect NetCore source code.

xtremertx
  • 121
  • 8

2 Answers2

4

Unsafe.CopyBlock - memcpy ?

Unsafe.CopyBlockUnaligned - will omit compiler check for aligned memory ?

This is probably no longer useful to OP, but I thought I'd point out that it is the opposite.

CopyBlock - omits the alignment check (meaning it will throw exception if CPU does not support unaligned pointers).

CopyBlockUnaligned - includes the safety check (it adds additional code to properly handle unaligned pointers). It is not a compiler check since pointers can't be validated at compile time, but an additional IL instruction.

Nikita B
  • 3,303
  • 1
  • 23
  • 41
2

I have found out that following methods are heavily optimized based on the data length you are trying to copy.

If source and destination memory overlaps they will use memmove (aligning and moving memory), otherwise bulkcopy (copying data in chunks)

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void __BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount);

[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern unsafe void __Memmove(byte* dest, byte* src, nuint len);

Array.Copy, Buffer.BlockCopy, Buffer.MemoryCopy, Span.CopyTo, Span.TryCopyTo are calling a generic Buffer.Memmove that will decide which one of the two to use.

System.Buffer.MemoryCopy seems to use a custom implementation instead of calling the native memcpy function or using the cpblk instruction (and it seems to dynamically switch between a (custom) memcpy and a QCall memmove).

Some answers that helped:
How is Array.Copy implemented in C#?
Where is the implementation of "_Memmove" in the core library souce code

xtremertx
  • 121
  • 8