-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory<byte> from Pointer ... for a possible MemoryMappedViewAccessor extension method #55881
Comments
Tagging subscribers to this area: @GrabYourPitchforks, @dotnet/area-system-memory Issue DetailsIs there a way to implement/generate a Memory<byte> from a pointer? Or is, by definition, Memory<byte> always GC managed memory? I'm asking the question here, because here are the high-performance code experts. Here is the scenario: I have a 128 GiB memory mapped file, which so far I expose with Span<byte> in ranges (as Span is limited to 2 GiB, but that is fine). I'm not using MemoryMappedViewAccessor, it's not a very useful class, I directly bind to windows API MapViewOfFile() and receive a pointer which I only expose as Span<byte> from a helper class, so this code is as safe and reliable as class MemoryMappedViewAccessor. This gives a lot of performance advantages, especially as many net core functions accept Span<byte> as input parameter. But there are also some issues with it, as Task cannot uses Span<byte> due to stack location. So far, I use a helper class that transfers a Span by extracting the pointer, and then regenerating that Span inside the Task function. It's hacky, but it works great and the performance gain is extreme. And yes, the Span<byte> originator is pinned correctly as well if needed. And the lifetime of the memory object is ensured as well. None of that is an issue. But I would prefer if I could use a Memory<byte> instead with valid memory ownership. But I'm not sure if that is even possible. And it would explain why MemoryMappedViewAccessor has no Memory<byte> accessor out of the box.
|
You can create your own |
Oh, now I get it. MemoryManager<T>.CreateMemory does not allocate memory, it returns a Memory<T> object with that length property only. That helps. The limitation of 2 GiB is not an issue. All Span<T>, Memory<T>, Range, Index are limited that way. The memory mapped file is segmented anyway with each segment below 64 MiB. If all works out, I will expand MemoryMappedViewAccessor (actually UnmanagedMemoryAccessor) with a "Memory<T> UnmanagedMemoryAccessor.GetMemory(Int64)" function. |
Related: #37227 |
Just a detail, but
Unless I am missing something, you are redoing |
Oh, I did not know about that pointer access ability. And I actually didn't expect SafeHandle to expose the base address pointer. Good to know. |
As @huoyaoyuan mentioned, I think the API aspect of this issue is a dupe of #37227. @hopperpl, is there anything else to address from a question perspective, or can we resolve the issue? |
I have it now working with a Memory accessor. Thanks to all. |
Is there a way to implement/generate a Memory<byte> from a pointer? Or is, by definition, Memory<byte> always GC managed memory?
I'm asking the question here, because here are the high-performance code experts.
Here is the scenario: I have a 128 GiB memory mapped file, which so far I expose with Span<byte> in ranges (as Span is limited to 2 GiB, but that is fine). I'm not using MemoryMappedViewAccessor, it's not a very useful class, I directly bind to windows API MapViewOfFile() and receive a pointer which I only expose as Span<byte> from a helper class, so this code is as safe and reliable as class MemoryMappedViewAccessor.
This gives a lot of performance advantages, especially as many net core functions accept Span<byte> as input parameter. But there are also some issues with it, as Task cannot uses Span<byte> due to stack location. So far, I use a helper class that transfers a Span by extracting the pointer, and then regenerating that Span inside the Task function. It's hacky, but it works great and the performance gain is extreme. And yes, the Span<byte> originator is pinned correctly as well if needed. And the lifetime of the memory object is ensured as well. None of that is an issue.
But I would prefer if I could use a Memory<byte> instead with valid memory ownership. But I'm not sure if that is even possible. And it would explain why MemoryMappedViewAccessor has no Memory<byte> accessor out of the box.
The text was updated successfully, but these errors were encountered: