例如,我想创建一个Vector256变量,并将所有元素初始化为指定的带符号整数,假设我的系统支持Avx2。.NET文档显示,使用Avx2广播标量使用
_mm256_broadcastd_epi32
和_mm_broadcastd_epi32
指令。
Vector256.Create
生成哪个指令?它与上述指令相同吗?int value = -1;
Vector256<int> v1 = Avx2.BroadcastScalarToVector256(&value);
Vector256<int> v2 = Vector256.Create(-1);
Debug.Assert(v1.Equals(v2)); // True
_mm256_broadcastd_epi32
是C内置函数,而不是汇编指令。由于C#不会编译成C再转换为汇编语言,因此这是糟糕的文档说明...但是,如果可能的话,它将使用从内存中加载的vpbroadcastd
,否则如果该值在寄存器中,则使用vmovd xmm0, ecx
/vpbroadcastd ymm0, xmm0
(如果该值在寄存器中)。参考链接:https://www.felixcloutier.com/x86/vpbroadcast。(或者使用AVX512VL,希望是`vpbroadcastd ymm0, ecx`)。有一种方法可以查看从C# JIT编译的汇编代码,我记得甚至有一个在线编译器浏览器类型的网站,但我忘了它是什么,因为我自己不使用C#。 - Peter Cordes_mm256_set1_epi32( value )
通常会从内存常量中加载值(理想情况下是广播加载),或者对于特殊情况,如零或-1,使用vpxor xmm0,xmm0,xmm0
来将 YMM0 清零,或者使用vpcmpeqd ymm0,ymm0,ymm0
将寄存器设置为全1,而不会对旧值产生错误依赖。 - Peter CordesVector256.Create
需要一个常量参数或者其他什么东西吗? - Peter CordesBroadcastScalarToVector256
真的想成为广播加载,并且将首先存储一个变量。Vector256.Create(func_arg)
将会执行vmovd
/vpbroadcastd ymm0, xmm0
。https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKGIAYACY8gOgBEBLbAcwDsJcGDmFwBuGvSasASgFdeQ/DBYBJBVA69cwsRMbMWchRyWr1m7SJYANABxJx1CQGYmpBgGEGAbxoN/TK7yuNgAZjAMAGowYBjQpACsSAA8mhgAfAwAsuQAFACUPn4BJcQA7FExcVCJSCwesNgYMLlw5PmOJQC+xf69gQzBYRHRsfFJqQqZWaS5aQwAbtgANrIwhb7UJSUA9DvlDACCCwikLABCUBDYACZgeBgAyvfL2FAAKhCj1bW5AGRLVbrTrbfwHb7jOoNGBNFqAtYdfo9ahdIA= - Peter Cordes