-
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
Span<T> #6168
Comments
|
I just love it, hope for some up-for-grabs issues! |
Does "Add Span to framework contracts" include items like adding to Stream Read/Write etc? Or is it making Span available as a type? (Assuming latter, and others will be new issues after) |
The CoreFxLab's prototype has useful extensions methods for |
Would there be any sane method to allow Span<> to integrate with List<> that it could operate on the underlying array? |
@omariom, we need the corfxlab API and the corlcr one to be the same (portable). The reason for it is that I think we need to use the corfxlab implementation for previously shipped runtime/frameworks, e.g. .NET Framework 4.5. Otherwise, the addoption of Span will be very much inhibited by inability to write portable code. Of course, the out-of-band span will be slower, but as long as the API is available in portable code, we should be good. |
@benaadams, we need some existing APIs, e.g. Stream.Read/Write to accept spans, but I think it's a separate workitem form the one @jkotas listed. |
@dotnetchris, what do you consider "sane" in this context? If you mean wrapping Span into List then no (Span is stack only, and does not always have "underlying array"). |
@adamsitnik, I am not sure we want completely open up for grabs so early (as there is lots of tricky work here) but you have done lots of good work in corfxlab and so if you (presonally) would like to take dotnet/coreclr#5857, it would be great! Same for @omariom :-) |
@KrzysztofCwalina Thanks! consider it done ;) |
@KrzysztofCwalina i meant for Span to access List's internal array |
I think we might also need to constrain T to primitive type (i.e. type with no managed object references). Otherwise, it will be possible to create Span over native memory without GC being aware of the roots. |
@KrzysztofCwalina |
@dotnetchris, yes, it would be great to add |
@omariom, it seems like accessors and copy operations too, e.g. Similarly when an array backed span of object sis copied to native span. |
@KrzysztofCwalina |
For these kind of operations, I think the blittability should be enforced via a dynamic check if needed, that the JIT can eliminate by treating it as intrinsic; or by Roslyn analyzer. I do not think it makes sense to have first class blittable constrain - it is too much complexity, for the value that it provides. Also, the casting between different blitable Span types is pretty questionable operation. It has portability problems because of it lets you create misaligned Spans. I do not think it should be in the "safe" Span API set. (Having it in "unsafe" span API set is fine.) |
When you are doing interop with unmanaged pointers, you have to know what you are doing and you have to get it right. If you do not get it right, your program will crash in a very bad way. In your example, the GC will not track the native memory and your program will crash in a very bad way. It is no different from if you pass wrong len to I know that we have historically tried to prevent some of the bad uses, but I always had mixed feelings about it. Maybe we should have the dynamic check for blitability in the regular |
I think it would be really good to have a "unsafe" span API set for high perf scenarios. As long as there will be a code path without unnecessary checks in cases where you know what you are doing. Also I hope it will still be possible to query the span whether it is based on native or managed memory and have access to native pointer or managed array/pinning depending on which memory is used. |
If For CoreLab's Span another solution should be found. May be Reflection? Though it will be slow. |
For It is probably pretty slow (haven't benchmarked it) on first call, but should then be fast perhaps even inlineable. The helper is also discussed in a blog post: http://aakinshin.net/en/blog/dotnet/blittable/ |
Using |
The ability to convert from say The language already has this exact concept in the spec under the guise struct Point { int x; int y }
void M<T>() where T : blittable // implies struct
M<Point>() // Okay
M<object>() // Nope, not blittable |
Could even have a safe convert where it checks You can already have explicit layout overlapping arrays; but the length property gets confused as its based on the instantiation type (which makes sense); but the span approach could have the appropriate length for each sized datatype. Example use reading from stream/disk/network from byte[] => Vector3[] or saving Vector3[] => byte[] |
@nblumhardt, the operations you listed could be extension methods over ROS, couldn't they? |
@KrzysztofCwalina yes, though the ergonomics of extension methods are still second-rate because of the need to add a Tooling helps, and is improving, but at present it's still easier to find members on a type than it is to find extensions. The prevalence of "remove unused usings" as an automated refactoring means Even if the extension method route is preferred, could the character-oriented extensions like (Stretching a little further, would implementing and optimizing the most common string-like methods on Thanks for the reply, apologies if I missed earlier discussions around this BTW :-) |
I've been (somewhat) following development of the C# Slicing issue, but I'm having trouble understanding how exactly these two issues are related. A few questions to clear things up:
Overall, I'm in huge favor of having a mechanism (like Sorry to interrupt - as a mostly passive observer, I might have missed some details. |
@ilexp it's a bit confusing because the ability to have efficient slices requires both runtime and language work.
|
@KrzysztofCwalina |
@davidfowl did not say that Span will not work in F#. Today, C# does not implement these checks either, and Span works in C#. The checks just make it easier for the programmer using it to use it correctly. In the absence of the checks, the runtime will throw at runtime. |
Performance optimizations - dotnet/coreclr#9161 completed. |
When Span will land in .NET Framework? |
Spec docs link is wrong, actual is https://github.com/dotnet/corefxlab/blob/master/docs/specs/span.md |
@WillSullivan Updated - thanks. |
@HFadeel, Span<T> is in System.Memory nuget package. This package works on .NET Framework. |
Updated the milestone to 2.1. We need to go through the list above and make sure that there is nothing major falling through the cracks for |
thanks for giving this a nudge @jkotas |
Besides the VM correctness and stress workitems, I still worry that debug-ability of code using Spans is a pretty big issue. I will turn lots of people off spans. |
Why so negative? This api is for scenarios that are not exact everyone’s cup of tea. Don’t see anything bad about the api and design. |
It is about calling methods on Span or that take Span arguments via reflection:
|
Marking "Debugging" and "APIs for working with specialty spans" as complete. Also "VM - Correctness" and "VM - Stress" are done. What's left:
|
What is the possibility of adding a var dbPath = "test.txt";
var initialSize = 1024;
var mmf = MemoryMappedFile.CreateFromFile(dbPath);
var mma = mmf.CreateViewAccessor(0, initialSize).SafeMemoryMappedViewHandle;
Span<byte> bytes;
unsafe
{
byte* ptrMemMap = (byte*)0;
mma.AcquirePointer(ref ptrMemMap);
bytes = new Span<byte>(ptrMemMap, (int)mma.ByteLength);
} Also, it seems like I can only create var dbPath = "test.txt";
var initialSize = 1024;
var mmf = MemoryMappedFile.CreateFromFile(dbPath);
var mma = mmf.CreateViewAccessor(0, initialSize).SafeMemoryMappedViewHandle;
var mem = new Memory(mma);
var span = mem.Span.Slice(0, 512); I also noticed that the indexer and internal length of |
https://github.com/dotnet/corefx/issues/26603 has the discussion about Span & memory mapped files. |
Unfortunately, looking at https://github.com/dotnet/corefx/issues/26603 along with the referenced code in the benchmarks didn't clear things up for me. It seems like that particular use case is geared to copying small bits of the memory mapped files into |
@KrzysztofCwalina I think we should create something first class with Memory mapped files and the new buffer primitives (ReadOnlySequence). @kstewart83 all we have right now are extremely low level primitives that you have to string together to make something work. That specific issue was about the performance gap between using Span directly and using the ReadOnlySequence (the gap has been reduced for that specific scenario). Dealing with anything bigger than an int you'll need to use |
I have re-opened the dotnet/corefx#26603 issue. Feel free to move the discussion there (See https://github.com/dotnet/corefx/issues/26603#issuecomment-370306008). |
@ahsonkhan Is there more work on this issue for 2.1? |
There is no other work for 2.1. There are two items left from the original list, but both are marked as future. They can be tracked separately (and outside of 2.1):
Closing this issue! |
Turn https://github.com/dotnet/corefxlab/tree/master/src/System.Slices into efficient first class feature.
Better optimization for CORINFO_HELP_RUNTIMEHANDLE_METHODdotnet/coreclr#10051 [moved to future]Span<T>
to framework contractsSpan<T>
testsSpan<T>
andReadOnlySpan<T>
as yet another ByRef-like type in Roslyn, so that unsupported operations onSpan<T>
like boxing or creatingSpan<T>[]
are compile errors: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/span-safety.mdSpan<T>
for interopThe text was updated successfully, but these errors were encountered: