System.Numerics中SIMD启用类型用法确认:x写法是否未利用SIMD?
关于Vector4 SIMD优化的疑问
先看这段C#代码示例:
public void Test(float a, float b, float c, float d) { // not SIMD-enabled since we multiply ourselves? var x = new Vector4(a * d, b * c, c * b, d * a); var y = new Vector4(a, b, c, d); var z = new Vector4(d, c, b, a); // gets SIMD-enabled as done by the intrisics? var w = y * y; }
最初的推测是:
- 变量
x没有启用SIMD,因为是手动计算乘法结果后传入构造函数 - 变量
w是正确的SIMD用法
但查看Vector4的源代码后发现,其构造函数带有非公开的[Intrinsic]特性:
[Intrinsic] public Vector4(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; }
由此产生疑问:x的写法是否未利用SIMD,只有z或w的写法才会利用SIMD?
解答
关于
x的写法
你手动计算的a*d、b*c等都是标量乘法,这些运算会被CPU以标量方式执行,之后才把结果传入Vector4构造函数。哪怕构造函数带有[Intrinsic]特性,这个特性只是告诉编译器可以用内在函数优化构造过程(比如直接把四个值加载到SIMD寄存器),但之前的标量乘法已经无法被合并为SIMD向量乘法了。所以x的写法确实没有利用SIMD执行乘法运算,构造阶段的SIMD优化也只是加载数据,没有提升计算效率。关于
w的写法y * y是Vector4的重载乘法运算符,这个运算符本身是被SIMD优化的——编译器会直接生成SIMD指令,一次性完成四个元素的乘法运算,完全利用了SIMD的并行计算能力,这是正确的SIMD用法。关于
z的写法z只是把四个标量值传入构造函数,构造过程会借助[Intrinsic]特性优化为SIMD寄存器加载操作,但这里没有任何计算逻辑,只是数据的打包,不存在SIMD计算优化的说法。
总结:只有w的写法真正利用SIMD完成了计算优化;x的乘法是标量运算,无法利用SIMD并行计算;z只是SIMD友好的数据加载,没有计算层面的SIMD利用。
内容的提问来源于stack exchange,提问作者aybe
相关产品推荐
相关产品推荐

