Runtime: Documentation needed : Don`t use "ref" or "in" for hardware intrinsic vector structures for performance

Created on 15 May 2020  路  6Comments  路  Source: dotnet/runtime

In C# ,in or ref readonly features are useful to get better performance with passing large structure.
But,how does it works for hardware accelerated vectors?
(e.g. System.Numerics.Vector<T>,System.Runtime.Intrinsics.Vector256<T>)
These structures are huge,but it stores in register.
Because ref is a GC-tracked pointer.it never references register.
I think ref Vector256<T> causes load and store from memory repeatedly,and it is harmful for performance,but I could not find out any document about this.

area-Meta question

Most helpful comment

There aren't, strictly speaking, any hard rules here and what is beneficial depends on a number of factors.

For example on x86 Windows under any of the currently supported calling conventions the SIMD types will be passed by shadow copy and returned via a return buffer. While on x64 Windows the default calling convention passes by shadow copy but returns in XMM0/YMM0.
On x64 Unix, the first handful of parameters can be passed in register and there is additionally support for some HFA/HVAs (structs comprised of 1-4 floats/vectors) which can be passed in multiple registers. The same is possible on Windows when using __vectorcall but that isn't supported today.
As @Gnbrkm41 pointed out, none of this really matters if the code is inlined but having it not be address taken can improve codegen as the JIT doesn't need to try to remove the byref.

At the end of the day, the decision to pass by reference (ref), by readonly reference (in) or by value likely comes down to the exact code being executed and what platforms you plan on supporting.

All 6 comments

Just pass them around as normal arguments (i.e. w/o ref, in), and the JIT tries it's best to use the specific registers available (xmm for SSE, ymm for AVX / vex-encoded, etc.).

If concerned about perf, check the generated assembly (cf. Viewing JIT Dumps) to see what the JIT generates.

@gfoidl
Thanks!
I think it should be documented on MSDN.

Last time I looked about this on sharplab, the arguments were not passed using vector registers on Windows due to calling conventions, but @tannergooding explained that in most cases this shouldn't be a big problem because methods in hot paths should ideally be inlined anyway.

There aren't, strictly speaking, any hard rules here and what is beneficial depends on a number of factors.

For example on x86 Windows under any of the currently supported calling conventions the SIMD types will be passed by shadow copy and returned via a return buffer. While on x64 Windows the default calling convention passes by shadow copy but returns in XMM0/YMM0.
On x64 Unix, the first handful of parameters can be passed in register and there is additionally support for some HFA/HVAs (structs comprised of 1-4 floats/vectors) which can be passed in multiple registers. The same is possible on Windows when using __vectorcall but that isn't supported today.
As @Gnbrkm41 pointed out, none of this really matters if the code is inlined but having it not be address taken can improve codegen as the JIT doesn't need to try to remove the byref.

At the end of the day, the decision to pass by reference (ref), by readonly reference (in) or by value likely comes down to the exact code being executed and what platforms you plan on supporting.

Well,I previously said that how could we get best performance with "passing",
but I also meant that...

Which one is better to get Vector as bytes ?

  • vector.AsBytes()
    Seems like causing copy...
  • Unsafe.As<Vector256<T>,Vector256<byte>>(ref vector)
    Seems like never referencing register directly...

vector.AsBytes shouldn't cause a copy; it is a no-op to make the compiler happy, and the JIT should eliminate the call. I'd prefer the AsBytes method over Unsafe.As.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matty-hall picture matty-hall  路  3Comments

Timovzl picture Timovzl  路  3Comments

v0l picture v0l  路  3Comments

sahithreddyk picture sahithreddyk  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments