Uh oh!
There was an error while loading. Please reload this page.
SequenceReader performance; elide bounds checks and book-keeping - #82765
SequenceReader performance; elide bounds checks and book-keeping#82765mgravell wants to merge 23 commits into
Conversation
ghost
commented
Feb 28, 2023
Tagging subscribers to this area: @dotnet/area-system-memory Issue Detailscontext: https://twitter.com/marcgravell/status/1629955240895078405 (read back for @davidfowl mention) purpose: improved performance in approach:
|
15569c8 to
3ee60f6CompareUh oh!
There was an error while loading. Please reload this page.
mgravell
commented
Feb 28, 2023
@stephentoub well, I won't pretend not to be disappointed - however, thoughts on just reducing the book-keeping etc? |
stephentoub
commented
Mar 1, 2023
If there are safe ways of making it faster/smaller/etc., that's great, let's do it. And as I noted, I expect there are ways of writing the code differently such that bounds checks can be eliminated even without using Unsafe. |
mgravell
commented
Mar 1, 2023
@stephentoub fair enough; I have switched back from the unsafe to indexed, but improved a bunch of other related things :) |
f748b4e to
ed64ca8Comparemgravell
commented
Mar 1, 2023
disclosure: I'm not currently able to run the tests locally (although it builds cleanly):
I've tried about 30 things, but I can't get that working right now, and I can't find an idiot-proof guide to making it happy. |
stephentoub
commented
Mar 1, 2023
How are you building and running tests? |
mgravell
commented
Mar 1, 2023
locally, with .net8 preview installed; at command-line, in root, |
stephentoub
commented
Mar 1, 2023
Make sure you've done a clean build of the repo from root first, e.g. and only then try to iterate on a specific library Note as well that using |
mgravell
commented
Mar 1, 2023
done all that (using
(because it does not exist) |
interestingly, results: | Method | Job | Runtime | SegmentLength | Mean | Error | StdDev ||-------------- |--------- |--------- |-------------- |-----------:|---------:|---------:|| SystemTryPeek | .NET 6.0 | .NET 6.0 | -1024 | 747.2 ns | 14.42 ns | 14.81 ns || CustomTryPeek | .NET 6.0 | .NET 6.0 | -1024 | 687.9 ns | 9.98 ns | 9.33 ns || SystemTryPeek | .NET 6.0 | .NET 6.0 | 4 | 749.9 ns | 11.27 ns | 9.99 ns || CustomTryPeek | .NET 6.0 | .NET 6.0 | 4 | 692.4 ns | 11.89 ns | 10.54 ns || SystemTryPeek | .NET 6.0 | .NET 6.0 | 128 | 742.4 ns | 10.89 ns | 10.19 ns || CustomTryPeek | .NET 6.0 | .NET 6.0 | 128 | 690.3 ns | 9.60 ns | 8.98 ns || SystemTryPeek | .NET 6.0 | .NET 6.0 | 1024 | 743.5 ns | 5.95 ns | 5.56 ns || CustomTryPeek | .NET 6.0 | .NET 6.0 | 1024 | 682.0 ns | 3.82 ns | 3.57 ns || | | | | | | || SystemTryPeek | .NET 7.0 | .NET 7.0 | -1024 | 679.6 ns | 8.15 ns | 7.23 ns || CustomTryPeek | .NET 7.0 | .NET 7.0 | -1024 | 1,121.2 ns | 12.48 ns | 9.74 ns || SystemTryPeek | .NET 7.0 | .NET 7.0 | 4 | 683.3 ns | 11.10 ns | 10.38 ns || CustomTryPeek | .NET 7.0 | .NET 7.0 | 4 | 1,123.8 ns | 9.98 ns | 8.33 ns || SystemTryPeek | .NET 7.0 | .NET 7.0 | 128 | 685.8 ns | 9.32 ns | 8.72 ns || CustomTryPeek | .NET 7.0 | .NET 7.0 | 128 | 1,118.5 ns | 10.64 ns | 9.95 ns || SystemTryPeek | .NET 7.0 | .NET 7.0 | 1024 | 679.0 ns | 6.24 ns | 5.84 ns || CustomTryPeek | .NET 7.0 | .NET 7.0 | 1024 | 1,116.6 ns | 6.57 ns | 5.49 ns || | | | | | | || SystemTryPeek | .NET 8.0 | .NET 8.0 | -1024 | 704.7 ns | 13.94 ns | 25.50 ns || CustomTryPeek | .NET 8.0 | .NET 8.0 | -1024 | 630.5 ns | 8.47 ns | 7.92 ns || SystemTryPeek | .NET 8.0 | .NET 8.0 | 4 | 690.5 ns | 9.48 ns | 8.86 ns || CustomTryPeek | .NET 8.0 | .NET 8.0 | 4 | 625.4 ns | 5.49 ns | 4.59 ns || SystemTryPeek | .NET 8.0 | .NET 8.0 | 128 | 686.4 ns | 8.86 ns | 8.29 ns || CustomTryPeek | .NET 8.0 | .NET 8.0 | 128 | 624.5 ns | 5.68 ns | 5.31 ns || SystemTryPeek | .NET 8.0 | .NET 8.0 | 1024 | 696.3 ns | 12.07 ns | 10.70 ns || CustomTryPeek | .NET 8.0 | .NET 8.0 | 1024 | 631.1 ns | 8.28 ns | 7.74 ns |(I also yanked the |
stephentoub
commented
Mar 2, 2023
I'm not sure why there's a .NET 7 regression, but regardless of target, I suggest trying pulling the fields into locals prior to doing the comparison; you can do it in a way that'll result in smaller code and no bounds check: |
@stephentoub ironically despite the demonstrably better opcode, that tweak actually seems to react negatively in tests, on net7 and net8 - again like I'm hitting some JIT regression; if you look at net6, it looks great! but:
should I flag these somewhere else? I can put a fully runnable version somewhere | Method | Job | Runtime | SegmentLength | Mean | Error | StdDev | Ratio | RatioSD ||--------------- |--------- |--------- |-------------- |-----------:|---------:|---------:|------:|--------:|| SystemTryPeek | .NET 6.0 | .NET 6.0 | -1024 | 743.3 ns | 11.42 ns | 10.69 ns | 1.00 | 0.00 || CustomTryPeek | .NET 6.0 | .NET 6.0 | -1024 | 675.4 ns | 1.86 ns | 1.55 ns | 0.91 | 0.01 || CustomTryPeek2 | .NET 6.0 | .NET 6.0 | -1024 | 622.8 ns | 5.77 ns | 5.12 ns | 0.84 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 6.0 | .NET 6.0 | 4 | 734.8 ns | 8.49 ns | 7.53 ns | 1.00 | 0.00 || CustomTryPeek | .NET 6.0 | .NET 6.0 | 4 | 673.0 ns | 1.06 ns | 0.99 ns | 0.92 | 0.01 || CustomTryPeek2 | .NET 6.0 | .NET 6.0 | 4 | 620.6 ns | 5.98 ns | 5.00 ns | 0.84 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 6.0 | .NET 6.0 | 128 | 744.8 ns | 10.64 ns | 9.95 ns | 1.00 | 0.00 || CustomTryPeek | .NET 6.0 | .NET 6.0 | 128 | 681.8 ns | 8.88 ns | 8.31 ns | 0.92 | 0.02 || CustomTryPeek2 | .NET 6.0 | .NET 6.0 | 128 | 629.0 ns | 9.74 ns | 9.11 ns | 0.84 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 6.0 | .NET 6.0 | 1024 | 732.0 ns | 3.34 ns | 2.96 ns | 1.00 | 0.00 || CustomTryPeek | .NET 6.0 | .NET 6.0 | 1024 | 678.1 ns | 4.33 ns | 4.05 ns | 0.93 | 0.01 || CustomTryPeek2 | .NET 6.0 | .NET 6.0 | 1024 | 618.9 ns | 2.27 ns | 1.89 ns | 0.85 | 0.00 || | | | | | | | | || SystemTryPeek | .NET 7.0 | .NET 7.0 | -1024 | 672.4 ns | 2.22 ns | 1.97 ns | 1.00 | 0.00 || CustomTryPeek | .NET 7.0 | .NET 7.0 | -1024 | 1,112.8 ns | 9.43 ns | 8.82 ns | 1.65 | 0.01 || CustomTryPeek2 | .NET 7.0 | .NET 7.0 | -1024 | 891.5 ns | 2.13 ns | 1.89 ns | 1.33 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 7.0 | .NET 7.0 | 4 | 673.8 ns | 3.40 ns | 2.84 ns | 1.00 | 0.00 || CustomTryPeek | .NET 7.0 | .NET 7.0 | 4 | 1,143.1 ns | 22.19 ns | 24.66 ns | 1.69 | 0.03 || CustomTryPeek2 | .NET 7.0 | .NET 7.0 | 4 | 895.9 ns | 10.14 ns | 8.99 ns | 1.33 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 7.0 | .NET 7.0 | 128 | 676.0 ns | 4.09 ns | 3.63 ns | 1.00 | 0.00 || CustomTryPeek | .NET 7.0 | .NET 7.0 | 128 | 1,123.0 ns | 17.91 ns | 16.76 ns | 1.66 | 0.03 || CustomTryPeek2 | .NET 7.0 | .NET 7.0 | 128 | 895.3 ns | 6.10 ns | 5.41 ns | 1.32 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 7.0 | .NET 7.0 | 1024 | 682.5 ns | 8.38 ns | 7.84 ns | 1.00 | 0.00 || CustomTryPeek | .NET 7.0 | .NET 7.0 | 1024 | 1,125.3 ns | 18.56 ns | 17.36 ns | 1.65 | 0.03 || CustomTryPeek2 | .NET 7.0 | .NET 7.0 | 1024 | 899.3 ns | 9.17 ns | 8.57 ns | 1.32 | 0.02 || | | | | | | | | || SystemTryPeek | .NET 8.0 | .NET 8.0 | -1024 | 670.7 ns | 1.06 ns | 0.94 ns | 1.00 | 0.00 || CustomTryPeek | .NET 8.0 | .NET 8.0 | -1024 | 619.8 ns | 4.84 ns | 4.29 ns | 0.92 | 0.01 || CustomTryPeek2 | .NET 8.0 | .NET 8.0 | -1024 | 1,116.0 ns | 13.13 ns | 10.96 ns | 1.66 | 0.02 || | | | | | | | | || SystemTryPeek | .NET 8.0 | .NET 8.0 | 4 | 673.0 ns | 1.18 ns | 0.98 ns | 1.00 | 0.00 || CustomTryPeek | .NET 8.0 | .NET 8.0 | 4 | 625.0 ns | 7.32 ns | 6.85 ns | 0.93 | 0.01 || CustomTryPeek2 | .NET 8.0 | .NET 8.0 | 4 | 1,131.7 ns | 11.41 ns | 10.67 ns | 1.68 | 0.01 || | | | | | | | | || SystemTryPeek | .NET 8.0 | .NET 8.0 | 128 | 683.7 ns | 6.76 ns | 6.32 ns | 1.00 | 0.00 || CustomTryPeek | .NET 8.0 | .NET 8.0 | 128 | 633.2 ns | 9.56 ns | 8.94 ns | 0.93 | 0.01 || CustomTryPeek2 | .NET 8.0 | .NET 8.0 | 128 | 1,132.7 ns | 17.05 ns | 15.11 ns | 1.66 | 0.03 || | | | | | | | | || SystemTryPeek | .NET 8.0 | .NET 8.0 | 1024 | 683.4 ns | 10.02 ns | 9.37 ns | 1.00 | 0.00 || CustomTryPeek | .NET 8.0 | .NET 8.0 | 1024 | 629.9 ns | 10.97 ns | 10.26 ns | 0.92 | 0.02 || CustomTryPeek2 | .NET 8.0 | .NET 8.0 | 1024 | 1,136.0 ns | 21.21 ns | 20.84 ns | 1.66 | 0.03 |fortunately "read" is fine with the hoist everywhere: | Method | Job | Runtime | SegmentLength | Mean | Error | StdDev | Ratio | RatioSD ||--------------- |--------- |--------- |-------------- |---------:|----------:|----------:|------:|--------:|| SystemTryRead | .NET 6.0 | .NET 6.0 | -1024 | 1.596 us | 0.0177 us | 0.0166 us | 1.00 | 0.00 || CustomTryRead | .NET 6.0 | .NET 6.0 | -1024 | 1.557 us | 0.0088 us | 0.0083 us | 0.98 | 0.01 || CustomTryRead2 | .NET 6.0 | .NET 6.0 | -1024 | 1.344 us | 0.0014 us | 0.0011 us | 0.84 | 0.01 || | | | | | | | | || SystemTryRead | .NET 6.0 | .NET 6.0 | 4 | 4.028 us | 0.0630 us | 0.0590 us | 1.00 | 0.00 || CustomTryRead | .NET 6.0 | .NET 6.0 | 4 | 2.628 us | 0.0301 us | 0.0281 us | 0.65 | 0.01 || CustomTryRead2 | .NET 6.0 | .NET 6.0 | 4 | 2.552 us | 0.0234 us | 0.0219 us | 0.63 | 0.01 || | | | | | | | | || SystemTryRead | .NET 6.0 | .NET 6.0 | 128 | 1.697 us | 0.0128 us | 0.0120 us | 1.00 | 0.00 || CustomTryRead | .NET 6.0 | .NET 6.0 | 128 | 1.870 us | 0.0169 us | 0.0150 us | 1.10 | 0.01 || CustomTryRead2 | .NET 6.0 | .NET 6.0 | 128 | 1.454 us | 0.0031 us | 0.0026 us | 0.86 | 0.01 || | | | | | | | | || SystemTryRead | .NET 6.0 | .NET 6.0 | 1024 | 1.480 us | 0.0132 us | 0.0124 us | 1.00 | 0.00 || CustomTryRead | .NET 6.0 | .NET 6.0 | 1024 | 1.657 us | 0.0063 us | 0.0056 us | 1.12 | 0.01 || CustomTryRead2 | .NET 6.0 | .NET 6.0 | 1024 | 1.345 us | 0.0074 us | 0.0062 us | 0.91 | 0.01 || | | | | | | | | || SystemTryRead | .NET 7.0 | .NET 7.0 | -1024 | 1.560 us | 0.0111 us | 0.0099 us | 1.00 | 0.00 || CustomTryRead | .NET 7.0 | .NET 7.0 | -1024 | 1.574 us | 0.0051 us | 0.0042 us | 1.01 | 0.01 || CustomTryRead2 | .NET 7.0 | .NET 7.0 | -1024 | 1.147 us | 0.0227 us | 0.0212 us | 0.74 | 0.02 || | | | | | | | | || SystemTryRead | .NET 7.0 | .NET 7.0 | 4 | 3.971 us | 0.0777 us | 0.0864 us | 1.00 | 0.00 || CustomTryRead | .NET 7.0 | .NET 7.0 | 4 | 2.501 us | 0.0488 us | 0.0432 us | 0.63 | 0.02 || CustomTryRead2 | .NET 7.0 | .NET 7.0 | 4 | 2.628 us | 0.0496 us | 0.0509 us | 0.66 | 0.02 || | | | | | | | | || SystemTryRead | .NET 7.0 | .NET 7.0 | 128 | 1.681 us | 0.0065 us | 0.0060 us | 1.00 | 0.00 || CustomTryRead | .NET 7.0 | .NET 7.0 | 128 | 1.734 us | 0.0033 us | 0.0026 us | 1.03 | 0.00 || CustomTryRead2 | .NET 7.0 | .NET 7.0 | 128 | 1.232 us | 0.0029 us | 0.0026 us | 0.73 | 0.00 || | | | | | | | | || SystemTryRead | .NET 7.0 | .NET 7.0 | 1024 | 1.566 us | 0.0080 us | 0.0071 us | 1.00 | 0.00 || CustomTryRead | .NET 7.0 | .NET 7.0 | 1024 | 1.722 us | 0.0031 us | 0.0027 us | 1.10 | 0.01 || CustomTryRead2 | .NET 7.0 | .NET 7.0 | 1024 | 1.138 us | 0.0183 us | 0.0172 us | 0.73 | 0.01 || | | | | | | | | || SystemTryRead | .NET 8.0 | .NET 8.0 | -1024 | 1.385 us | 0.0260 us | 0.0319 us | 1.00 | 0.00 || CustomTryRead | .NET 8.0 | .NET 8.0 | -1024 | 1.365 us | 0.0217 us | 0.0203 us | 0.98 | 0.02 || CustomTryRead2 | .NET 8.0 | .NET 8.0 | -1024 | 1.135 us | 0.0056 us | 0.0052 us | 0.81 | 0.02 || | | | | | | | | || SystemTryRead | .NET 8.0 | .NET 8.0 | 4 | 3.519 us | 0.0283 us | 0.0251 us | 1.00 | 0.00 || CustomTryRead | .NET 8.0 | .NET 8.0 | 4 | 2.917 us | 0.0302 us | 0.0267 us | 0.83 | 0.01 || CustomTryRead2 | .NET 8.0 | .NET 8.0 | 4 | 2.295 us | 0.0203 us | 0.0180 us | 0.65 | 0.01 || | | | | | | | | || SystemTryRead | .NET 8.0 | .NET 8.0 | 128 | 1.482 us | 0.0193 us | 0.0181 us | 1.00 | 0.00 || CustomTryRead | .NET 8.0 | .NET 8.0 | 128 | 1.453 us | 0.0068 us | 0.0060 us | 0.98 | 0.01 || CustomTryRead2 | .NET 8.0 | .NET 8.0 | 128 | 1.256 us | 0.0039 us | 0.0033 us | 0.85 | 0.01 || | | | | | | | | || SystemTryRead | .NET 8.0 | .NET 8.0 | 1024 | 1.348 us | 0.0107 us | 0.0095 us | 1.00 | 0.00 || CustomTryRead | .NET 8.0 | .NET 8.0 | 1024 | 1.350 us | 0.0058 us | 0.0055 us | 1.00 | 0.01 || CustomTryRead2 | .NET 8.0 | .NET 8.0 | 1024 | 1.131 us | 0.0027 us | 0.0026 us | 0.84 | 0.01 | |
adamsitnik
commented
May 22, 2023
@mgravell Is my understanding correct that it improves perf on .NET 6 and 7, but for unknown reason regresses on 8? Is there any way I could help you with getting this PR merged (beside the code review ofc)? I could run it on my hardware for .NET 8 main vs PR and get the trace files/disassembly if needed. |
- implement custom buffer advance API; avoids need to store "next", plus faster - add position validity assertions
I managed to rebase this PR on top of main and compared the results against main. There are very nice improvements with the exception of Results |
f32fd66 to
e825679Comparejozkee
commented
Aug 17, 2023
@EgorBo@tannergooding I'm trying to understand the reason of a regression (modified in this PR) on SequenceReader.TryRead when the segments are small i.e: the longer the loop, the bigger the regression. Any advice you could give here of which may be causing it? The benchmark in question: [Benchmark]publicintSystemTryRead(){varreader=newSystem.Buffers.SequenceReader<int>(payload);intcount=0;while(reader.TryRead(out_)){count++;}returncount;}New TryRead (inlined in SystemTryRead benchmark)Disassembly:; System.Memory.SequenceReaderBenchmark.SystemTryRead()pushr15pushr14pushr13pushrdipushrsipushrbppushrbxsubrsp,0A0vzeroupper vxorps xmm4,xmm4,xmm4 vmovdqa xmmword ptr [rsp+20],xmm4 vmovdqa xmmword ptr [rsp+30],xmm4movrax,0FFFFFFFFFFFFFFA0M00_L00: vmovdqa xmmword ptr [rsp+rax+0A0],xmm4 vmovdqa xmmword ptr [rsp+rax+0B0],xmm4 vmovdqa xmmword ptr [rsp+rax+0C0],xmm4addrax,30jne short M00_L00 vmovdqu xmm0,xmmword ptr [rcx+10] vmovdqu xmmword ptr [rsp+40],xmm0movrdx,[rcx+20]mov[rsp+50],rdx vmovdqu xmm0,xmmword ptr [rsp+40] vmovdqu xmmword ptr [rsp+78],xmm0movrcx,[rsp+50]mov[rsp+88],rcxmovrcx,[rsp+40]movedx,[rsp+50]andedx,7FFFFFFFmov[rsp+58],rcxmov[rsp+70],edxmovr8,[rsp+40]testr8,r8je near ptr M00_L17movebx,[rsp+50]movesi,[rsp+54]xoredi,edicmpr8,[rsp+48] setne dilmovecx,ebxorecx,esijl near ptr M00_L15movrax,r8movrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rax],rcxjne near ptr M00_L10M00_L01:movrcx,[rax+18]movebp,[rax+20]movr14d,[rax+24]xorr15d,r15dxorr13d,r13dtestrcx,rcxje short M00_L03movrax,[rcx]test dword ptr [rax],80000000je near ptr M00_L11lear15,[rcx+10]movr13d,[rcx+8]M00_L02:andebp,7FFFFFFFmovecx,ebpmoveax,r14daddrax,rcxmovedx,r13dcmprax,rdxja near ptr M00_L13lear15,[r15+rcx*4]movr13d,r14dM00_L03:testedi,edije near ptr M00_L12cmpebx,r13dja near ptr M00_L13movecx,ebxlearcx,[r15+rcx*4]subr13d,ebxmov[rsp+30],rcxmov[rsp+38],r13dM00_L04: vmovdqu xmm0,xmmword ptr [rsp+30] vmovdqu xmmword ptr [rsp+90],xmm0xorecx,ecxmov[rsp+74],ecxmov[rsp+68],rcxmovrcx,[rsp+40]cmprcx,[rsp+48]je near ptr M00_L18mov qword ptr [rsp+60],0FFFFFFFFFFFFFFFFcmp dword ptr [rsp+98],0je near ptr M00_L16M00_L05:xoredi,ediM00_L06:movecx,[rsp+74]movrax,[rsp+90]movedx,[rsp+98]cmpecx,edxjae short M00_L08movr8d,ecxmoveax,[rax+r8*4]incecxmov[rsp+74],ecxcmpecx,edxje short M00_L09M00_L07:incedijmp short M00_L06M00_L08:moveax,ediaddrsp,0A0poprbxpoprbppoprsipoprdipopr13popr14popr15retM00_L09:learcx,[rsp+58]call qword ptr [7FFB2D246100]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()jmp short M00_L07M00_L10:movrdx,r8call qword ptr [7FFB2CD343F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)jmp near ptr M00_L01M00_L11:leardx,[rsp+20]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movr15,[rsp+20]movr13d,[rsp+28]jmp near ptr M00_L02M00_L12:subesi,ebxmoveax,ebxmovecx,esiaddrax,rcxmovecx,r13dcmprax,rcxjbe short M00_L14M00_L13:call qword ptr [7FFB2D0657B8]int3M00_L14:movecx,ebxlearcx,[r15+rcx*4]mov[rsp+30],rcxmov[rsp+38],esijmp near ptr M00_L04M00_L15:learcx,[rsp+40]leardx,[rsp+30]movr9d,edicall qword ptr [7FFB2D0E4300]jmp near ptr M00_L04M00_L16:learcx,[rsp+58]call qword ptr [7FFB2D246100]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()jmp near ptr M00_L05M00_L17: vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+30],xmm0jmp near ptr M00_L04M00_L18:movsxdrcx,dword ptr [rsp+98]mov[rsp+60],rcxjmp near ptr M00_L05; Total bytes of code 632; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,38xoreax,eaxmov[rsp+28],raxmovrbx,rcxmovesi,[rbx+40]leardx,[rbx+20]movrcx,rbxleardi,[rcx+38]movrbp,[rdx+8]movr14d,[rdx+14]andr14d,7FFFFFFFmovr15d,1movrdx,[rcx]movrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]call qword ptr [7FFB2CD34360]; System.Runtime.CompilerServices.CastHelpers.IsInstanceOfClass(Void*, System.Object)movr13,raxtestr13,r13je short M01_L04M01_L00:cmpr13,rbpje short M01_L04movr13,[r13+8]movrcx,rbxmovrdx,r13call CORINFO_HELP_CHECKED_ASSIGN_REFtestr13,r13je short M01_L04movrcx,[r13+18]movr12d,[r13+20]movr15d,[r13+24]xoreax,eaxxoredx,edxtestrcx,rcxje short M01_L02movrax,[rcx]test dword ptr [rax],80000000je near ptr M01_L11learax,[rcx+10]movedx,[rcx+8]M01_L01:andr12d,7FFFFFFFmovecx,r12dmovr8d,r15daddr8,rcxmovedx,edxcmpr8,rdxja near ptr M01_L09learax,[rax+rcx*4]movedx,r15dM01_L02:mov[rdi],raxmov[rdi+8],edxcmpr13,rbpje short M01_L07M01_L03:cmp dword ptr [rdi+8],0je short M01_L08xorr15d,r15dM01_L04:testr15d,r15djne short M01_L05xoreax,eaxmov[rbx+1C],eaxmov[rbx+18],eaxmovsxdrax,esiadd[rbx+10],raxmoveax,1addrsp,38poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM01_L05:cmpr15d,2je short M01_L10mov[rbx+1C],esiM01_L06:xoreax,eaxaddrsp,38poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM01_L07:moveax,r14dcmpeax,[rdi+8]ja short M01_L09movrax,[rdi]mov[rdi],raxmov[rdi+8],r14djmp short M01_L03M01_L08:movr15d,2jmp near ptr M01_L00M01_L09:call qword ptr [7FFB2D0657B8]int3M01_L10:xoreax,eaxmov[rbx+1C],eaxmov[rbx+18],eaxmovsxdrax,esiadd[rbx+10],raxjmp short M01_L06M01_L11:leardx,[rsp+28]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movrax,[rsp+28]movedx,[rsp+30]jmp near ptr M01_L01; Total bytes of code 364Old TryReadDisassembly:; System.Memory.SequenceReaderBenchmark.SystemTryRead()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,0D8vzeroupperxoreax,eaxmov[rsp+38],rax vxorps xmm4,xmm4,xmm4movrax,0FFFFFFFFFFFFFF70M00_L00: vmovdqa xmmword ptr [rsp+rax+0D0],xmm4 vmovdqa xmmword ptr [rsp+rax+0E0],xmm4 vmovdqa xmmword ptr [rsp+rax+0F0],xmm4addrax,30jne short M00_L00mov[rsp+0D0],raxmovrbx,[rcx+10]movrsi,[rcx+18]movedi,[rcx+20]movebp,[rcx+24]mov[rsp+0B0],rbxmov[rsp+0B8],rsimov[rsp+0C0],edimov[rsp+0C4],ebpmovecx,ediandecx,7FFFFFFFmov[rsp+90],rbxmov[rsp+98],ecxmov qword ptr [rsp+78],0FFFFFFFFFFFFFFFF vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+0A0],xmm0movrcx,rbxtestrcx,rcxje near ptr M00_L16xorr14d,r14dcmprbx,rsi setne r14btestedi,edijl near ptr M00_L26testebp,ebpjl near ptr M00_L25movrcx,rbxmovrdx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rcx],rdxjne near ptr M00_L04M00_L01:movrcx,rbxmovrdx,[rcx+18]movr15d,[rcx+20]movr13d,[rcx+24]xorr12d,r12dxorecx,ecxmov[rsp+30],rdxtestrdx,rdxje short M00_L03movrcx,[rdx]test dword ptr [rcx],80000000je near ptr M00_L23lear12,[rdx+10]movecx,[rdx+8]M00_L02:andr15d,7FFFFFFFmovedx,r15dmoveax,r13daddrax,rdxmovecx,ecxcmprax,rcxja near ptr M00_L21lear12,[r12+rdx*4]movecx,r13dM00_L03:mov[rsp+68],r12mov[rsp+70],ecxtestr14d,r14dje near ptr M00_L24cmpedi,[rsp+70]ja near ptr M00_L21movrcx,[rsp+68]movedx,edilearcx,[rcx+rdx*4]movedx,[rsp+70]subedx,edimov[rsp+68],rcxmov[rsp+70],edxmovrcx,[rbx+8]mov[rsp+0A0],rcxxorecx,ecxmov[rsp+0A8],ecxjmp near ptr M00_L16M00_L04:movrcx,rdxmovrdx,rbxcall qword ptr [7FFB2CD543F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)jmp near ptr M00_L01M00_L05:incr15dM00_L06:cmp byte ptr [rsp+8C],0je near ptr M00_L22movrcx,[rsp+0C8]movedx,[rsp+0D0]moveax,[rsp+88]movr8d,eaxcmpr8d,edxjae near ptr M00_L34movedx,r8dmovecx,[rcx+rdx*4]inceaxmov[rsp+88],eaxmovrcx,[rsp+80]incrcxmov[rsp+80],rcxmovecx,[rsp+88]movedx,[rsp+0D0]cmpecx,edxjl short M00_L05movrcx,[rsp+0B0]movr13,[rsp+0B8]cmprcx,r13je near ptr M00_L18jmp short M00_L09M00_L07:moveax,1M00_L08:mov[rsp+0A0],rbpxoredx,edxmov[rsp+0A8],edxtesteax,eaxje near ptr M00_L18jmp near ptr M00_L14M00_L09:movr12,[rsp+0A0]movesi,[rsp+0A8]movebx,esimovr13,[rsp+0B8]movecx,[rsp+0C0]movedi,[rsp+0C4]movrdx,[rsp+0A0]xorebp,ebptestrdx,rdxje near ptr M00_L28sarecx,1Fmoveax,edisareax,1Fleaecx,[rax+rcx*2]moveax,ecxnegeaxandedi,7FFFFFFFtesteax,eaxjne near ptr M00_L30movrax,rdxmovrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rax],rcxjne near ptr M00_L15M00_L10:cmprax,r13je near ptr M00_L29movrbp,[rax+8]testrbp,rbpje near ptr M00_L20movrcx,[rax+18]movr13d,[rax+20]movr14d,[rax+24]cmpesi,r14dja near ptr M00_L19addr13d,esisubr14d,esijmp near ptr M00_L07M00_L11:xoredx,edxxoreax,eaxtestrcx,rcxje short M00_L13movrdx,[rcx]test dword ptr [rdx],80000000je near ptr M00_L33leardx,[rcx+10]moveax,[rcx+8]M00_L12:andr13d,7FFFFFFFmovecx,r13dmovr8d,r14daddr8,rcxmoveax,eaxcmpr8,raxja near ptr M00_L21leardx,[rdx+rcx*4]moveax,r14dM00_L13:mov[rsp+0C8],rdxmov[rsp+0D0],eaxxoredx,edxmov[rsp+88],edxjmp near ptr M00_L05M00_L14:mov[rsp+90],r12mov[rsp+98],ebxtestr14d,r14djle near ptr M00_L32jmp short M00_L11M00_L15:call qword ptr [7FFB2CD543F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)jmp near ptr M00_L10M00_L16: vmovdqu xmm0,xmmword ptr [rsp+68] vmovdqu xmmword ptr [rsp+0C8],xmm0xorecx,ecxcmp dword ptr [rsp+70],0 setg clmov[rsp+8C],clcmp byte ptr [rsp+8C],0je near ptr M00_L27M00_L17:xorr15d,r15djmp near ptr M00_L06M00_L18:mov byte ptr [rsp+8C],0jmp near ptr M00_L05M00_L19:movecx,21call qword ptr [7FFB2D085B18]int3M00_L20:call qword ptr [7FFB2D264F18]int3M00_L21:call qword ptr [7FFB2D0857B8]int3M00_L22:moveax,r15daddrsp,0D8poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM00_L23:leardx,[rsp+58]movrcx,[rsp+30]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movr12,[rsp+58]movecx,[rsp+60]jmp near ptr M00_L02M00_L24:subebp,edimovedx,edimovecx,ebpaddrdx,rcxmovecx,[rsp+70]cmprdx,rcxja short M00_L21movrdx,[rsp+68]movecx,edileardx,[rdx+rcx*4]mov[rsp+68],rdxmov[rsp+70],ebpjmp near ptr M00_L16M00_L25:testr14d,r14djne short M00_L20movrdx,rbxmovrcx,offset MT_System.Int32[]call qword ptr [7FFB2CD54390]movecx,ebpandecx,7FFFFFFFsubecx,edimovedx,edimovr8d,ecxaddrdx,r8movr8d,[rbx+8]cmprdx,r8ja near ptr M00_L21movedx,edileardx,[rbx+rdx*4+10]mov[rsp+68],rdxmov[rsp+70],ecxjmp near ptr M00_L16M00_L26:mov[rsp+20],r14dlearcx,[rsp+68]movrdx,rbxmovr8d,edimovr9d,ebpcall qword ptr [7FFB2D1044B0]jmp near ptr M00_L16M00_L27:cmprbx,rsije near ptr M00_L17mov byte ptr [rsp+8C],1learcx,[rsp+78]call qword ptr [7FFB2D266250]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].GetNextSpan()jmp near ptr M00_L17M00_L28:xorecx,ecxxorr13d,r13dxorr14d,r14dxoreax,eaxjmp near ptr M00_L08M00_L29:movrcx,[rax+18]movr13d,[rax+20]movr14d,[rax+24]subedi,esimovedx,esimoveax,ediaddrdx,raxmoveax,r14dcmprdx,raxja near ptr M00_L19addesi,r13dmovr13d,esimovr14d,edijmp near ptr M00_L07M00_L30:cmprdx,r13jne near ptr M00_L20cmpeax,1jne short M00_L31movrcx,offset MT_System.Int32[]call qword ptr [7FFB2CD54390]movr14d,edisubr14d,esimovedx,esimovecx,r14daddrdx,rcxmovecx,[rax+8]cmprdx,rcxja near ptr M00_L21movrcx,raxmovr13d,esijmp near ptr M00_L07M00_L31:movrcx,offset MT_System.Buffers.MemoryManager`1[[System.Int32, System.Private.CoreLib]]call qword ptr [7FFB2CD543D8]; System.Runtime.CompilerServices.CastHelpers.ChkCastClass(Void*, System.Object)movrcx,raxleardx,[rsp+48]movrax,[rax]movrax,[rax+40]call qword ptr [rax+20]movr14d,edisubr14d,esimovedx,esimovecx,r14daddrdx,rcxmovecx,[rsp+54]cmprdx,rcxja near ptr M00_L21movrcx,[rsp+48]movr13d,esiaddr13d,[rsp+50]jmp near ptr M00_L07M00_L32: vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+0C8],xmm0xoredx,edxmov[rsp+88],edxjmp near ptr M00_L09M00_L33:leardx,[rsp+38]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movrdx,[rsp+38]moveax,[rsp+40]jmp near ptr M00_L12M00_L34:call CORINFO_HELP_RNGCHKFAILint3; Total bytes of code 1477; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].GetNextSpan()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,48 vxorps xmm4,xmm4,xmm4 vmovdqa xmmword ptr [rsp+20],xmm4 vmovdqa xmmword ptr [rsp+30],xmm4movrbx,rcxmovrcx,[rbx+38]movrsi,[rbx+40]cmprcx,rsije near ptr M02_L07M02_L00:movrdx,[rbx+28]movrdi,rdxmovebp,[rbx+30]movrsi,[rbx+40]movecx,[rbx+48]movr14d,[rbx+4C]lear15,[rbx+28]xorr13d,r13dtestrdx,rdxje near ptr M02_L08sarecx,1Fmoveax,r14dsareax,1Fleaecx,[rax+rcx*2]movr12d,ecxnegr12dmoveax,[r15+8]mov[rsp+40],eaxandr14d,7FFFFFFFtestr12d,r12djne near ptr M02_L11movr12,rdxmovrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[r12],rcxjne near ptr M02_L06M02_L01:cmpr12,rsije near ptr M02_L10movr13,[r12+8]testr13,r13je near ptr M02_L14movrsi,[r12+18]movr14d,[r12+20]movr12d,[r12+24]moveax,[rsp+40]cmpeax,r12dja near ptr M02_L13addr14d,eaxsubr12d,eaxM02_L02:mov dword ptr [rsp+44],1M02_L03:movrcx,r15movrdx,r13call CORINFO_HELP_CHECKED_ASSIGN_REFxorecx,ecxmov[r15+8],ecxcmp dword ptr [rsp+44],0je near ptr M02_L07learcx,[rbx+18]movrdx,rdicall CORINFO_HELP_CHECKED_ASSIGN_REFmov[rbx+20],ebptestr12d,r12djle near ptr M02_L09xoredx,edxxorecx,ecxtestrsi,rsije short M02_L05movrdx,[rsi]test dword ptr [rdx],80000000je near ptr M02_L15leardx,[rsi+10]movecx,[rsi+8]M02_L04:andr14d,7FFFFFFFmoveax,r14dmovr8d,r12daddr8,raxmovecx,ecxcmpr8,rcxja near ptr M02_L16leardx,[rdx+rax*4]movecx,r12dM02_L05:mov[rbx+50],rdxmov[rbx+58],ecxxoredx,edxmov[rbx+10],edxaddrsp,48poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM02_L06:call qword ptr [7FFB2CD543F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)movr12,raxjmp near ptr M02_L01M02_L07:mov byte ptr [rbx+14],0addrsp,48poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM02_L08:xoresi,esixorr14d,r14dxorr12d,r12dxoreax,eaxxoredx,edxmov[rsp+44],edxjmp near ptr M02_L03M02_L09:xorecx,ecxmov[rbx+50],rcxmov[rbx+58],rcxmov[rbx+10],ecxjmp near ptr M02_L00M02_L10:movrsi,[r12+18]movedx,[r12+20]movr12d,[r12+24]moveax,[rsp+40]subr14d,eaxmovecx,eaxmovr8d,r14daddrcx,r8movr8d,r12dcmprcx,r8ja near ptr M02_L13addeax,edxmovr12d,r14dmovr14d,eaxjmp near ptr M02_L02M02_L11:cmprdx,rsijne near ptr M02_L14cmpr12d,1jne short M02_L12movrcx,offset MT_System.Int32[]call qword ptr [7FFB2CD54390]movesi,[rsp+40]movr12d,r14dsubr12d,esimovedx,esimovecx,r12daddrdx,rcxmovecx,[rax+8]cmprdx,rcxja near ptr M02_L16movr14d,esimovrsi,raxjmp near ptr M02_L02M02_L12:movrcx,offset MT_System.Buffers.MemoryManager`1[[System.Int32, System.Private.CoreLib]]call qword ptr [7FFB2CD543D8]; System.Runtime.CompilerServices.CastHelpers.ChkCastClass(Void*, System.Object)movrcx,raxleardx,[rsp+30]movrax,[rax]movrax,[rax+40]call qword ptr [rax+20]movesi,[rsp+40]movr12d,r14dsubr12d,esimovecx,esimoveax,r12daddrcx,raxmoveax,[rsp+3C]cmprcx,raxja short M02_L16movrcx,[rsp+30]movr14d,esiaddr14d,[rsp+38]movrsi,rcxjmp near ptr M02_L02M02_L13:movecx,21call qword ptr [7FFB2D085B18]int3M02_L14:call qword ptr [7FFB2D264F18]int3M02_L15:leardx,[rsp+20]movrcx,rsimovrax,[rsi]movrax,[rax+40]call qword ptr [rax+28]movrdx,[rsp+20]movecx,[rsp+28]jmp near ptr M02_L04M02_L16:call qword ptr [7FFB2D0857B8]int3; Total bytes of code 706 |
jozkee
commented
Aug 17, 2023
[Benchmark]publicvoidSystemTryReadTo(){varreader=newSystem.Buffers.SequenceReader<int>(payload);if(reader.TryReadTo(outReadOnlySpan<int>_,255))Throw();}New TryReadToDisassembly:; System.Memory.SequenceReaderBenchmark.SystemTryReadTo()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,198vzeroupperxoreax,eaxmov[rsp+28],rax vxorps xmm4,xmm4,xmm4 vmovdqa xmmword ptr [rsp+30],xmm4movrax,0FFFFFFFFFFFFFEB0M00_L00: vmovdqa xmmword ptr [rsp+rax+190],xmm4 vmovdqa xmmword ptr [rsp+rax+1A0],xmm4 vmovdqa xmmword ptr [rsp+rax+1B0],xmm4addrax,30jne short M00_L00mov[rsp+190],rax vmovdqu xmm0,xmmword ptr [rcx+10] vmovdqu xmmword ptr [rsp+128],xmm0movrdx,[rcx+20]mov[rsp+138],rdx vmovdqu xmm0,xmmword ptr [rsp+128] vmovdqu xmmword ptr [rsp+170],xmm0movrcx,[rsp+138]mov[rsp+180],rcxmovrcx,[rsp+128]movedx,[rsp+138]andedx,7FFFFFFFmov[rsp+150],rcxmov[rsp+168],edxmovr8,[rsp+128]testr8,r8je near ptr M00_L26movebx,[rsp+138]movebp,[rsp+13C]xorr14d,r14dcmpr8,[rsp+130] setne r14bmovecx,ebxorecx,ebpjl near ptr M00_L14movrax,r8movrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rax],rcxjne near ptr M00_L11M00_L01:movrcx,[rax+18]movr15d,[rax+20]movr13d,[rax+24]xorr12d,r12dxorr8d,r8dtestrcx,rcxje short M00_L03movr8,[rcx]test dword ptr [r8],80000000je near ptr M00_L12lear12,[rcx+10]movr8d,[rcx+8]M00_L02:andr15d,7FFFFFFFmovecx,r15dmovedx,r13daddrdx,rcxmovr8d,r8dcmprdx,r8ja near ptr M00_L17lear12,[r12+rcx*4]movr8d,r13dM00_L03:testr14d,r14dje near ptr M00_L13cmpebx,r8dja near ptr M00_L17movecx,ebxlearcx,[r12+rcx*4]subr8d,ebxmov[rsp+118],rcxmov[rsp+120],r8dM00_L04: vmovdqu xmm0,xmmword ptr [rsp+118] vmovdqu xmmword ptr [rsp+188],xmm0xorecx,ecxmov[rsp+16C],ecxmov[rsp+160],rcxmovrcx,[rsp+128]cmprcx,[rsp+130]je near ptr M00_L27mov qword ptr [rsp+158],0FFFFFFFFFFFFFFFFcmp dword ptr [rsp+190],0je near ptr M00_L15M00_L05:movecx,[rsp+16C]movr15d,[rsp+190]cmpecx,r15dja near ptr M00_L17movr8,[rsp+188]movedx,ecxlear13,[r8+rdx*4]subr15d,ecxmovrcx,r13movr8d,r15dmovedx,0FFcall qword ptr [7FFB2D27CF18]; System.SpanHelpers.NonPackedIndexOfValueType[[System.Int32, System.Private.CoreLib],[System.SpanHelpers+DontNegate`1[[System.Int32, System.Private.CoreLib]], System.Private.CoreLib]](Int32 ByRef, Int32, Int32)cmpeax,0FFFFFFFFjne near ptr M00_L16movr14d,[rsp+190]subr14d,[rsp+16C]leardi,[rsp+88]learsi,[rsp+150]movecx,9repmovsqtestr14d,r14djle short M00_L06movsxdrdx,r14dlearcx,[rsp+150]call qword ptr [7FFB2D276FD0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].Advance(Int64)M00_L06:learcx,[rsp+188]leardx,[rsp+78]movr8d,[rsp+16C]call qword ptr [7FFB2CD5FA98]; System.ReadOnlySpan`1[[System.Int32, System.Private.CoreLib]].Slice(Int32)learcx,[rsp+150]call qword ptr [7FFB2D276E20]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].get_End()testeax,eaxjne short M00_L08M00_L07: vmovdqu xmm0,xmmword ptr [rsp+78] vmovdqu xmmword ptr [rsp+48],xmm0learcx,[rsp+48]movedx,0FFcall qword ptr [7FFB2D27C300]; System.MemoryExtensions.IndexOf[[System.Int32, System.Private.CoreLib]](System.ReadOnlySpan`1<Int32>, Int32)cmpeax,0FFFFFFFFjne near ptr M00_L21movedx,[rsp+80]learcx,[rsp+150]call qword ptr [7FFB2D276FE8]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].AdvanceCurrentSpan(Int64) vmovdqu xmm0,xmmword ptr [rsp+188] vmovdqu xmmword ptr [rsp+78],xmm0learcx,[rsp+150]call qword ptr [7FFB2D276E20]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].get_End()testeax,eaxje short M00_L07M00_L08:leardi,[rsp+150]learsi,[rsp+88]movecx,9repmovsq vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+0F0],xmm0 vmovdqu xmmword ptr [rsp+0F8],xmm0 vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+140],xmm0xoresi,esiM00_L09:testesi,esijne near ptr M00_L25M00_L10:addrsp,198poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM00_L11:movrdx,r8call qword ptr [7FFB2CD543F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)jmp near ptr M00_L01M00_L12:leardx,[rsp+108]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movr12,[rsp+108]movr8d,[rsp+110]jmp near ptr M00_L02M00_L13:subebp,ebxmovecx,ebxmovedx,ebpaddrcx,rdxmovedx,r8dcmprcx,rdxja short M00_L17movecx,ebxlearcx,[r12+rcx*4]mov[rsp+118],rcxmov[rsp+120],ebpjmp near ptr M00_L04M00_L14:learcx,[rsp+128]leardx,[rsp+118]movr9d,r14dcall qword ptr [7FFB2D0C50B0]jmp near ptr M00_L04M00_L15:learcx,[rsp+150]call qword ptr [7FFB2D276FA0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()jmp near ptr M00_L05M00_L16:learbx,[rsp+140]testeax,eaxje short M00_L19cmpeax,r15djbe short M00_L18M00_L17:call qword ptr [7FFB2D0857B8]int3M00_L18:movecx,eaxjmp short M00_L20M00_L19:xorr13d,r13dxorecx,ecxM00_L20:mov[rbx],r13mov[rbx+8],ecxmovecx,[rsp+16C]leaecx,[rcx+rax+1]mov[rsp+16C],ecxmovecx,[rsp+16C]cmpecx,[rsp+190]jne near ptr M00_L25learcx,[rsp+150]call qword ptr [7FFB2D276FA0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()jmp near ptr M00_L25M00_L21:testeax,eaxjle short M00_L22movsxdrdx,eaxlearcx,[rsp+150]call qword ptr [7FFB2D276FE8]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].AdvanceCurrentSpan(Int64)M00_L22:movrbx,[rsp+88]movesi,[rsp+0A0]addesi,[rsp+0A4]learcx,[rsp+150]leardx,[rsp+68]call qword ptr [7FFB2D276E68]mov[rsp+38],rbxmov[rsp+40],esi vmovdqu xmm0,xmmword ptr [rsp+68] vmovdqu xmmword ptr [rsp+28],xmm0lear8,[rsp+38]lear9,[rsp+28]learcx,[rsp+170]leardx,[rsp+0F0]call qword ptr [7FFB2D0C4F60]learcx,[rsp+150]movedx,1call qword ptr [7FFB2D276FD0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].Advance(Int64)learbx,[rsp+140]movrcx,[rsp+0F0]cmprcx,[rsp+0F8]je short M00_L23learcx,[rsp+0F0]call qword ptr [7FFB2D27DE78]movrdx,rax vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+58],xmm0learcx,[rsp+58]call qword ptr [7FFB2CD5F870] vmovdqu xmm0,xmmword ptr [rsp+58] vmovdqu xmmword ptr [rsp+0D0],xmm0jmp short M00_L24M00_L23:learcx,[rsp+0F0]leardx,[rsp+0E0]call qword ptr [7FFB2D0C5068]learcx,[rsp+0E0]leardx,[rsp+0D0]call qword ptr [7FFB2D275B48]; System.ReadOnlyMemory`1[[System.Int32, System.Private.CoreLib]].get_Span()M00_L24:movrax,[rsp+0D0]mov[rbx],raxmoveax,[rsp+0D8]mov[rbx+8],eaxmovesi,1jmp near ptr M00_L09M00_L25:call qword ptr [7FFB2D0C5368]jmp near ptr M00_L10M00_L26: vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+118],xmm0jmp near ptr M00_L04M00_L27:movsxdrcx,dword ptr [rsp+190]mov[rsp+158],rcxjmp near ptr M00_L05; Total bytes of code 1407; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].TryGetNextSpan()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,38xoreax,eaxmov[rsp+28],raxmovrbx,rcxmovesi,[rbx+40]leardx,[rbx+20]movrcx,rbxleardi,[rcx+38]movrbp,[rdx+8]movr14d,[rdx+14]andr14d,7FFFFFFFmovr15d,1movrdx,[rcx]movrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]call qword ptr [7FFB2CD54360]; System.Runtime.CompilerServices.CastHelpers.IsInstanceOfClass(Void*, System.Object)movr13,raxtestr13,r13je short M08_L04M08_L00:cmpr13,rbpje short M08_L04movr13,[r13+8]movrcx,rbxmovrdx,r13call CORINFO_HELP_CHECKED_ASSIGN_REFtestr13,r13je short M08_L04movrcx,[r13+18]movr12d,[r13+20]movr15d,[r13+24]xoreax,eaxxoredx,edxtestrcx,rcxje short M08_L02movrax,[rcx]test dword ptr [rax],80000000je near ptr M08_L08learax,[rcx+10]movedx,[rcx+8]M08_L01:andr12d,7FFFFFFFmovecx,r12dmovr8d,r15daddr8,rcxmovedx,edxcmpr8,rdxja near ptr M08_L10learax,[rax+rcx*4]movedx,r15dM08_L02:mov[rdi],raxmov[rdi+8],edxcmpr13,rbpje short M08_L05M08_L03:cmp dword ptr [rdi+8],0je short M08_L09xorr15d,r15dM08_L04:testr15d,r15djne short M08_L06xoreax,eaxmov[rbx+1C],eaxmov[rbx+18],eaxmovsxdrax,esiadd[rbx+10],raxmoveax,1addrsp,38poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM08_L05:moveax,r14dcmpeax,[rdi+8]ja short M08_L10movrax,[rdi]mov[rdi],raxmov[rdi+8],r14djmp short M08_L03M08_L06:cmpr15d,2je short M08_L11mov[rbx+1C],esiM08_L07:xoreax,eaxaddrsp,38poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM08_L08:leardx,[rsp+28]movrax,[rcx]movrax,[rax+40]call qword ptr [rax+28]movrax,[rsp+28]movedx,[rsp+30]jmp near ptr M08_L01M08_L09:movr15d,2jmp near ptr M08_L00M08_L10:call qword ptr [7FFB2D0857B8]int3M08_L11:xoreax,eaxmov[rbx+1C],eaxmov[rbx+18],eaxmovsxdrax,esiadd[rbx+10],raxjmp short M08_L07; Total bytes of code 364Old TryReadToDisassembly:; System.Memory.SequenceReaderBenchmark.SystemTryReadTo()pushr15pushr14pushr13pushr12pushrdipushrsipushrbppushrbxsubrsp,208vzeroupper vxorps xmm4,xmm4,xmm4 vmovdqa xmmword ptr [rsp+30],xmm4 vmovdqa xmmword ptr [rsp+40],xmm4movrax,0FFFFFFFFFFFFFE50M00_L00: vmovdqa xmmword ptr [rsp+rax+200],xmm4 vmovdqa xmmword ptr [rsp+rax+210],xmm4 vmovdqa xmmword ptr [rsp+rax+220],xmm4addrax,30jne short M00_L00mov[rsp+200],raxmovrbx,[rcx+10]movrbp,[rcx+18]movr14d,[rcx+20]movr15d,[rcx+24]mov[rsp+1E0],rbxmov[rsp+1E8],rbpmov[rsp+1F0],r14dmov[rsp+1F4],r15dmovecx,r14dandecx,7FFFFFFFmov[rsp+1C0],rbxmov[rsp+1C8],ecxmov qword ptr [rsp+1A8],0FFFFFFFFFFFFFFFF vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+1D0],xmm0movrcx,rbxtestrcx,rcxje near ptr M00_L10xorr13d,r13dcmprbx,rbp setne r13btestr14d,r14djl near ptr M00_L33testr15d,r15djl near ptr M00_L31movrcx,rbxmovrdx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rcx],rdxjne near ptr M00_L04M00_L01:movrcx,rbxmovr8,[rcx+18]movr12d,[rcx+20]movesi,[rcx+24]xorecx,ecxxoredx,edxtestr8,r8je short M00_L03movrcx,[r8]test dword ptr [rcx],80000000je near ptr M00_L29learcx,[r8+10]movedx,[r8+8]M00_L02:andr12d,7FFFFFFFmovr8d,r12dmoveax,esiaddrax,r8movedx,edxcmprax,rdxja near ptr M00_L21learcx,[rcx+r8*4]movedx,esiM00_L03:mov[rsp+188],rcxmov[rsp+190],edxtestr13d,r13dje near ptr M00_L30cmpr14d,[rsp+190]ja near ptr M00_L21movrcx,[rsp+188]movr8d,r14dlearcx,[rcx+r8*4]movr8d,[rsp+190]subr8d,r14dmov[rsp+188],rcxmov[rsp+190],r8dmovrcx,[rbx+8]mov[rsp+1D0],rcxxorecx,ecxmov[rsp+1D8],ecxjmp near ptr M00_L10M00_L04:movrcx,rdxmovrdx,rbxcall qword ptr [7FFB2CD243F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)jmp near ptr M00_L01M00_L05:movedx,r8dlearcx,[rcx+rdx*4]subesi,r8dcmp byte ptr [rsp+1BC],0je short M00_L07M00_L06:movr8d,esimovedx,0FFcall qword ptr [7FFB2D24D7A0]; System.SpanHelpers.NonPackedIndexOfValueType[[System.Int32, System.Private.CoreLib],[System.SpanHelpers+DontNegate`1[[System.Int32, System.Private.CoreLib]], System.Private.CoreLib]](Int32 ByRef, Int32, Int32)cmpeax,0FFFFFFFFjne near ptr M00_L22movedx,esilearcx,[rsp+1A8]call qword ptr [7FFB2D247120]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].AdvanceCurrentSpan(Int64)movrcx,[rsp+1F8]movesi,[rsp+200]cmp byte ptr [rsp+1BC],0jne short M00_L06M00_L07:leardi,[rsp+1A8]learsi,[rsp+0E0]movecx,0Crepmovsq vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+160],xmm0 vmovdqu xmmword ptr [rsp+168],xmm0 vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+198],xmm0xoresi,esiM00_L08:testesi,esijne near ptr M00_L28M00_L09:addrsp,208poprbxpoprbppoprsipoprdipopr12popr13popr14popr15retM00_L10: vmovdqu xmm0,xmmword ptr [rsp+188] vmovdqu xmmword ptr [rsp+1F8],xmm0xorecx,ecxcmp dword ptr [rsp+190],0 setg clmov[rsp+1BC],clcmp byte ptr [rsp+1BC],0je near ptr M00_L34M00_L11:movrcx,[rsp+1F8]movr12d,[rsp+200]movr8d,[rsp+1B8]cmpr8d,r12dja near ptr M00_L21movedx,r8dlearsi,[rcx+rdx*4]subr12d,r8dmovrcx,rsimovr8d,r12dmovedx,0FFcall qword ptr [7FFB2D24D7A0]; System.SpanHelpers.NonPackedIndexOfValueType[[System.Int32, System.Private.CoreLib],[System.SpanHelpers+DontNegate`1[[System.Int32, System.Private.CoreLib]], System.Private.CoreLib]](Int32 ByRef, Int32, Int32)cmpeax,0FFFFFFFFjne near ptr M00_L35movr13d,[rsp+200]subr13d,[rsp+1B8]leardi,[rsp+0E0]learsi,[rsp+1A8]movecx,0Crepmovsqtestr13d,r13djle near ptr M00_L17movsxdr13,r13dtestr13,0FFFFFFFF80000000jne short M00_L12movecx,[rsp+200]subecx,[rsp+1B8]cmpecx,r13djg near ptr M00_L38M00_L12:testr13,r13jl near ptr M00_L39movrcx,r13addrcx,[rsp+1B0]mov[rsp+1B0],rcxcmp byte ptr [rsp+1BC],0je near ptr M00_L16M00_L13:movecx,[rsp+200]subecx,[rsp+1B8]movsxdrdx,ecxcmprdx,r13jg near ptr M00_L19movedx,ecxaddedx,[rsp+1B8]mov[rsp+1B8],edxmovsxdrcx,ecxsubr13,rcx vmovdqu xmm0,xmmword ptr [rsp+1E0] vmovdqu xmmword ptr [rsp+90],xmm0movrcx,[rsp+1F0]mov[rsp+0A0],rcxmovrcx,[rsp+90]cmprcx,[rsp+98]je near ptr M00_L18M00_L14:movrsi,[rsp+1D0]movedi,[rsp+1D8] vmovdqu xmm0,xmmword ptr [rsp+1E0] vmovdqu xmmword ptr [rsp+90],xmm0movrcx,[rsp+1F0]mov[rsp+0A0],rcxlearcx,[rsp+90]leardx,[rsp+1D0]lear8,[rsp+80]lear9,[rsp+60]call qword ptr [7FFB2D095050]; System.Buffers.ReadOnlySequence`1[[System.Int32, System.Private.CoreLib]].TryGetBuffer(System.SequencePosition ByRef, System.ReadOnlyMemory`1<Int32> ByRef, System.SequencePosition ByRef) vmovdqu xmm0,xmmword ptr [rsp+60] vmovdqu xmmword ptr [rsp+1D0],xmm0testeax,eaxje near ptr M00_L18mov[rsp+1C0],rsimov[rsp+1C8],edicmp dword ptr [rsp+8C],0jle near ptr M00_L40learcx,[rsp+80]leardx,[rsp+70]call qword ptr [7FFB2D245B48]; System.ReadOnlyMemory`1[[System.Int32, System.Private.CoreLib]].get_Span() vmovdqu xmm0,xmmword ptr [rsp+70] vmovdqu xmmword ptr [rsp+1F8],xmm0xorecx,ecxmov[rsp+1B8],ecxM00_L15:testr13,r13je short M00_L16cmp byte ptr [rsp+1BC],0jne near ptr M00_L13M00_L16:testr13,r13jne short M00_L20M00_L17:movrcx,[rsp+1F8]movesi,[rsp+200]movr8d,[rsp+1B8]cmpr8d,esija short M00_L21jmp near ptr M00_L05M00_L18:mov byte ptr [rsp+1BC],0jmp short M00_L15M00_L19:movecx,r13daddecx,[rsp+1B8]mov[rsp+1B8],ecxjmp short M00_L17M00_L20:movrcx,[rsp+1B0]subrcx,r13mov[rsp+1B0],rcxmovecx,0Fcall qword ptr [7FFB2D245D58]int3M00_L21:call qword ptr [7FFB2D0557B8]int3M00_L22:testeax,eaxjle short M00_L23movsxdrcx,eaxmovrax,rcxaddrax,[rsp+1B0]mov[rsp+1B0],raxaddecx,[rsp+1B8]mov[rsp+1B8],ecxmovecx,[rsp+1B8]moveax,[rsp+200]cmpecx,eaxjl short M00_L23learcx,[rsp+1A8]call qword ptr [7FFB2D2470F0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].GetNextSpan()M00_L23: vmovdqu xmm0,xmmword ptr [rsp+1E0] vmovdqu xmmword ptr [rsp+0C8],xmm0movrcx,[rsp+1F0]mov[rsp+0D8],rcxlearcx,[rsp+0E0]leardx,[rsp+0B8]call qword ptr [7FFB2D246F70]learcx,[rsp+1A8]leardx,[rsp+0A8]call qword ptr [7FFB2D246F70] vmovdqu xmm0,xmmword ptr [rsp+0B8] vmovdqu xmmword ptr [rsp+40],xmm0 vmovdqu xmm0,xmmword ptr [rsp+0A8] vmovdqu xmmword ptr [rsp+30],xmm0lear8,[rsp+40]lear9,[rsp+30]learcx,[rsp+0C8]leardx,[rsp+160]call qword ptr [7FFB2D094F60]movecx,[rsp+200]subecx,[rsp+1B8]cmpecx,1jle short M00_L24movecx,[rsp+1B8]incecxmov[rsp+1B8],ecxmovrcx,[rsp+1B0]incrcxmov[rsp+1B0],rcxjmp short M00_L25M00_L24:learcx,[rsp+1A8]movedx,1call qword ptr [7FFB2D247138]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].AdvanceToNextSpan(Int64)M00_L25:learbx,[rsp+198]movrcx,[rsp+160]cmprcx,[rsp+168]je short M00_L26learcx,[rsp+160]call qword ptr [7FFB2D24E700]movrdx,rax vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+50],xmm0learcx,[rsp+50]call qword ptr [7FFB2CD2F870] vmovdqu xmm0,xmmword ptr [rsp+50] vmovdqu xmmword ptr [rsp+140],xmm0jmp short M00_L27M00_L26:learcx,[rsp+160]leardx,[rsp+150]call qword ptr [7FFB2D095068]learcx,[rsp+150]leardx,[rsp+140]call qword ptr [7FFB2D245B48]; System.ReadOnlyMemory`1[[System.Int32, System.Private.CoreLib]].get_Span()M00_L27:movrax,[rsp+140]mov[rbx],raxmoveax,[rsp+148]mov[rbx+8],eaxmovesi,1jmp near ptr M00_L08M00_L28:call qword ptr [7FFB2D095368]jmp near ptr M00_L09M00_L29:leardx,[rsp+178]movrcx,r8movrax,[r8]movrax,[rax+40]call qword ptr [rax+28]movrcx,[rsp+178]movedx,[rsp+180]jmp near ptr M00_L02M00_L30:subr15d,r14dmoveax,r14dmovecx,r15daddrax,rcxmovecx,[rsp+190]cmprax,rcxja near ptr M00_L21movrax,[rsp+188]movecx,r14dlearax,[rax+rcx*4]mov[rsp+188],raxmov[rsp+190],r15djmp near ptr M00_L10M00_L31:testr13d,r13dje short M00_L32call qword ptr [7FFB2D245DB8]int3M00_L32:movrdx,rbxmovrcx,offset MT_System.Int32[]call qword ptr [7FFB2CD24390]movecx,r15dandecx,7FFFFFFFsubecx,r14dmovedx,r14dmovr8d,ecxaddrdx,r8movr8d,[rbx+8]cmprdx,r8ja near ptr M00_L21movedx,r14dleardx,[rbx+rdx*4+10]mov[rsp+188],rdxmov[rsp+190],ecxjmp near ptr M00_L10M00_L33:mov[rsp+20],r13dlearcx,[rsp+188]movrdx,rbxmovr8d,r14dmovr9d,r15dcall qword ptr [7FFB2D095260]jmp near ptr M00_L10M00_L34:cmprbx,rbpje near ptr M00_L11mov byte ptr [rsp+1BC],1learcx,[rsp+1A8]call qword ptr [7FFB2D2470F0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].GetNextSpan()jmp near ptr M00_L11M00_L35:learcx,[rsp+198]testeax,eaxje short M00_L36cmpeax,r12dja near ptr M00_L21movedx,eaxjmp short M00_L37M00_L36:xoresi,esixoredx,edxM00_L37:mov[rcx],rsimov[rcx+8],edxinceaxmovsxdrcx,eaxmovrax,rcxaddrax,[rsp+1B0]mov[rsp+1B0],raxaddecx,[rsp+1B8]mov[rsp+1B8],ecxmovecx,[rsp+1B8]moveax,[rsp+200]cmpecx,eaxjl near ptr M00_L28learcx,[rsp+1A8]call qword ptr [7FFB2D2470F0]; System.Buffers.SequenceReader`1[[System.Int32, System.Private.CoreLib]].GetNextSpan()jmp near ptr M00_L28M00_L38:movecx,r13daddecx,[rsp+1B8]mov[rsp+1B8],ecxmovrcx,r13addrcx,[rsp+1B0]mov[rsp+1B0],rcxjmp near ptr M00_L17M00_L39:movecx,0Fcall qword ptr [7FFB2D245D58]int3M00_L40: vxorps xmm0,xmm0,xmm0 vmovdqu xmmword ptr [rsp+1F8],xmm0xorecx,ecxmov[rsp+1B8],ecxjmp near ptr M00_L14; Total bytes of code 2191; System.Buffers.ReadOnlySequence`1[[System.Int32, System.Private.CoreLib]].TryGetBuffer(System.SequencePosition ByRef, System.ReadOnlyMemory`1<Int32> ByRef, System.SequencePosition ByRef)pushr15pushr14pushrdipushrsipushrbppushrbxsubrsp,38xoreax,eaxmov[rsp+28],raxmovrbx,r8movrsi,r9movr8,[rdx]xoreax,eaxmov[rsi],raxmov[rsi+8],raxtestr8,r8je near ptr M04_L03moveax,[rcx+10]sareax,1Fmovedi,[rcx+14]movr10d,edisarr10d,1Fleaeax,[r10+rax*2]movebp,eaxnegebpmovr14,[rcx+8]movr15d,[rdx+8]andedi,7FFFFFFFtestebp,ebpjne near ptr M04_L05movrbp,r8movrcx,offset MT_System.Buffers.ReadOnlySequenceSegment`1[[System.Int32, System.Private.CoreLib]]cmp[rbp],rcxjne short M04_L02M04_L00:cmprbp,r14je short M04_L04movrdx,[rbp+8]testrdx,rdxje near ptr M04_L06movrcx,rsicall CORINFO_HELP_CHECKED_ASSIGN_REFxorecx,ecxmov[rsi+8],ecxmovrdx,[rbp+18]movr14d,[rbp+20]movesi,[rbp+24]cmpr15d,esija near ptr M04_L11addr14d,r15dsubesi,r15dmovrcx,rbxcall CORINFO_HELP_CHECKED_ASSIGN_REFmov[rbx+8],r14dmov[rbx+0C],esiM04_L01:moveax,1addrsp,38poprbxpoprbppoprsipoprdipopr14popr15retM04_L02:movrdx,r8call qword ptr [7FFB2CD243F0]; System.Runtime.CompilerServices.CastHelpers.ChkCastClassSpecial(Void*, System.Object)movrbp,raxjmp short M04_L00M04_L03:xoreax,eaxmov[rbx],raxmov[rbx+8],raxaddrsp,38poprbxpoprbppoprsipoprdipopr14popr15retM04_L04:movrdx,[rbp+18]movr14d,[rbp+20]movesi,[rbp+24]subedi,r15dmovecx,r15dmoveax,ediaddrcx,raxmoveax,esicmprcx,raxja near ptr M04_L11addr15d,r14dmovrcx,rbxcall CORINFO_HELP_CHECKED_ASSIGN_REFmov[rbx+8],r15dmov[rbx+0C],edijmp short M04_L01M04_L05:cmpr8,r14je short M04_L07M04_L06:call qword ptr [7FFB2D245DB8]int3M04_L07:cmpebp,1jne short M04_L08movrdx,r8movrcx,offset MT_System.Int32[]call qword ptr [7FFB2CD24390]movrdx,raxsubedi,r15dmovecx,r15dmoveax,ediaddrcx,raxmoveax,[rdx+8]cmprcx,raxja short M04_L09movrcx,rbxcall CORINFO_HELP_CHECKED_ASSIGN_REFmov[rbx+8],r15dmov[rbx+0C],edijmp near ptr M04_L01M04_L08:movrdx,r8movrcx,offset MT_System.Buffers.MemoryManager`1[[System.Int32, System.Private.CoreLib]]call qword ptr [7FFB2CD243D8]; System.Runtime.CompilerServices.CastHelpers.ChkCastClass(Void*, System.Object)movrcx,raxleardx,[rsp+28]movrax,[rax]movrax,[rax+40]call qword ptr [rax+20]movesi,edisubesi,r15dmoveax,r15dmovecx,esiaddrax,rcxmovecx,[rsp+34]cmprax,rcxjbe short M04_L10M04_L09:call qword ptr [7FFB2D0557B8]int3M04_L10:movrdx,[rsp+28]movedi,r15daddedi,[rsp+30]movrcx,rbxcall CORINFO_HELP_CHECKED_ASSIGN_REFmov[rbx+8],edimov[rbx+0C],esijmp near ptr M04_L01M04_L11:movecx,21call qword ptr [7FFB2D055B18]int3; Total bytes of code 477 |
stephentoub
commented
Jan 2, 2024
jozkee
commented
Jan 17, 2024
@stephentoub we need to check if there's something that can be made about the TryRead and TryReadTo regressions; if not, evaluate if this a valuable trade-off. |
stephentoub
commented
Jul 22, 2024
mgravell
commented
Jul 22, 2024
I would suggest that if there's still scope for it, that we bump it to net10 - a bit late in the cycle for nuanced reader things; nobody seems massively stoked either way, though, so honestly: I'm also fine with just burning it. I can work with local similar types when needed |
stephentoub
commented
Jul 22, 2024
Ok, let's try to either land it or close it early in 10. Thanks. |
stephentoub
commented
Mar 5, 2025
@mgravell, do you plan to continue working on this? |
context: https://twitter.com/marcgravell/status/1629955240895078405 (read back for @davidfowl mention)
no direct side-by-side benchmark (what's a good way to arrange that here? I'm all ears), but in a proof-of-concept benchmark (see link above), achieved ~0.7 vs existing (note: that number was in-part based on the now removed
ref Tchanges)purpose: improved performance in
SequenceReaderapproach:
remove bounds-checking (since we're checking the bounds ourselves) viaUnsafe.Add(ref T, int)when possible (net7+) store the current span'sref Tdirectly; otherwise, store theReadOnlySpan<T>like before, and use JIT-friendly accessor to expose the same API to the implementation codeSequencePositionfor packing purposes[0,len)loopTvalue (of unknown size); use therefinstead_currentPositionInteger(by obtaining the outer span and initializing_currentSpanIndexaccordingly), but because of padding that wouldn't help unless we were able to split out the_currentSpanintointplusref Tvia unsafe add etc, which would allow us to drop to 64 bytes)&inAdvance, since we expect both sides to pass in the happy path (and both are safe)benchmarks are here
(all payloads are 1024 bytes, split into chunks via
SegmentLength; if this is negative, it is a vector, rather than a multi-segment)typical results: https://raw.githubusercontent.com/mgravell/SequenceReaderBench/main/results.md
some similar benchmarks with
ref T+intusage (unsafe, etc) don't show significant improvements in any cases