Issue:
When writing interop code, it may be desirable to copy memory from one location to another. However, there is currently no managed API for doing so. As such, the user must manually implement such a function, which can be error prone and cannot take advantage of certain optimization techniques (such as using SIMD registers to copy aligned 16-byte blocks).
Workaround:
Use Buffer.MemoryCopy which is non-optimal for a few reasons (see https://github.com/dotnet/corefx/issues/10455#issuecomment-236372132), manually implement an API for marshalling memory, or DllImport the memcpy function from the C Runtime (this is non optimal as it does not necessarily exist in the same library on each platform).
Request:
An additional overload to Marshal.Copy should be provided in the form of public static void Copy(IntPtr source, IntPtr destination, int length). This would ideally end up as a call to memcpy behind the scenes.
It may additionally be useful to provide other memory interop functions, such as memmove (uses an intermediate buffer, allowing the source and destination to overlap), memcmp (allows comparing of two memory blocks), memchr (allows locating the first instance of a value in a memory buffer), and memset (allows filling a memory buffer with the specified value).
public static void Copy(IntPtr source, IntPtr destination, int length)
Presumably the existing Buffer.MemoryCopy is not a good fit because it uses unsafe pointers instead of IntPtr?
@mikedn, there are three issues with Buffer.MemoryCopy:
memmove and can end up using an intermediate buffer for copying, thus slowing down performance.Whether or not it the API is unsafe is of little consequence (at least to me) as I am already working with unsafe code and unmanaged memory.
can end up using an intermediate buffer for copying
It won't ever use intermediate buffer for copying.
not able to take advantage of XMM copy
It does take advantage of the XMM copy for large sizes via the PInvoke to memmove. It is not easy to make it to take advantage of XMM copy, with taking all iteractions with GC and exception handling into account, not introducing too much extra overhead, and not having to maintain and test a customized version of thousands of lines of assembly.
Also, the world is moving in a direction where the fastest way to do memory copy is old-fashioned rep movsb again. Hopefully, all the tricky logic on choosing the best way to do memory copy that had to be updated for each major processor release will be just wired into the silicon in future.
Related discussion https://github.com/dotnet/coreclr/issues/2430
This should be taken care of by Span<T> and the optimizations that went into Buffer.MemoryCopy (the managed implementation takes advantage of XMM registers on x64 now).
Most helpful comment
It won't ever use intermediate buffer for copying.
It does take advantage of the XMM copy for large sizes via the PInvoke to memmove. It is not easy to make it to take advantage of XMM copy, with taking all iteractions with GC and exception handling into account, not introducing too much extra overhead, and not having to maintain and test a customized version of thousands of lines of assembly.
Also, the world is moving in a direction where the fastest way to do memory copy is old-fashioned
rep movsbagain. Hopefully, all the tricky logic on choosing the best way to do memory copy that had to be updated for each major processor release will be just wired into the silicon in future.