Skip to content

Strange Span costs for as Memory.Span -> parameter #32396

@benaadams

Description

@benaadams

Can costs for passing Spans as parameters be reduced? (e.g. by passing in xmm registers).

The current costs may make passing pointers or refs more attractive; which is undesirable as it discards the bounding safety provided by the Spans.

Noticed in #32371 (comment) where the cost of using Span parameters for the method is higher than the method's time taken to test whether two sets of 4096 bytes are equal (test on Windows)

Created gist benchmark https://gist.github.com/benaadams/56af11cf7f8e0e1da3fed47464414f8a to demonstrate:

|                      Method |      Mean |     Error |    StdDev |
|---------------------------- |----------:|----------:|----------:|
|            PassSpansByParam |  9.982 ns | 0.0492 ns | 0.0460 ns |
|      PassDeconstructedSpans |  3.541 ns | 0.0496 ns | 0.0464 ns |
|          DeferSpansCreation |  3.513 ns | 0.0507 ns | 0.0475 ns |
|       PassSpansByParamTwice | 11.082 ns | 0.0417 ns | 0.0390 ns |
| PassReconstructedSpansParam |  5.014 ns | 0.0207 ns | 0.0172 ns |

All three methods create Spans from the same Memory<byte>

  • PassSpansByParam - passes the created Span<byte> as parameters
  • PassDeconstructedSpans - turns the Span<byte> into ref byte and int and passes those
  • DeferSpansCreation - passes no parameters and creates the Span<byte> in the callee
  • PassSpansByParamTwice - passes the created Span<byte> as parameters; then passes them through to second method in different param positions
  • PassReconstructedSpansParam - turns the Span<byte> into ref byte and int and passes those; then recreates the Spans from the params and passes those created Spans on to second method.

As PassSpansByParamTwice to see if its purely span passing (i.e. is the cost directly additive); it doesn't add the same cost on again; it seems to be more than purely parameter passing.

As PassReconstructedSpansParam does pass the Spans as parameters, just not from the original method that gets them from the Memory<byte> and has a much lower cost; even though it now involves an extra non-inlined method call, its even stranger?

category:cq
theme:optimization
skill-level:expert
cost:medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIoptimization

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions