我正在与SIMD一起玩,并考虑将其用于3D数学中的Vector运算。 代替
class Vec4f
{
float val[4];
//+operators here
}
我可以拥有
class SimdVec4f
{
__m128 val; //+operators
}
但是,由于__m128
只有8个可用寄存器,如果我想拥有8个以上的此类实例,会发生什么?编译器是否像通常的变量一样自行处理从内存到寄存器的加载,反之亦然?
感谢您的时间,并为我提供了一些见解。
答案 0 :(得分:4)
这与int
变量多于整数寄存器的情况完全相同:如果同时存在太多变量,则编译器可能不得不将它们溢出到内存中,稍后再加载。向量寄存器的寄存器分配与整数reg的寄存器分配几乎完全相同,可以分析函数的数据流并确定哪些变量同时存在。
您应该认为_mm_load_ps/loadu
和store/storeu
内在函数更多地描述了与向量类型之间的类型对合,而不是唯一可以编译为向量加载或存储指令的东西,或者始终编译为加载/存储。
顺便说一句,x86-64具有xmm0..15。如果要使代码需要多个寄存器来提高效率,可以编译为64位。
用于3D矢量的SSE:
通常避免在SIMD向量中保留单个方向/几何向量。您可以有效地添加,但是任何叉积或点积或长度计算都需要重新组合。
最好使用4个x
值的向量,4个y
值的向量等,以便可以并行计算4个长度。有关更多信息,请参见https://stackoverflow.com/tags/sse/info,尤其是这些幻灯片:
SIMD at Insomniac Games (GDC 2015)展示了如何布置数据以实现高效SIMD。 (数组的结构,而不是结构的数组)。
另请参阅Parallel programming using Haswell architecture
有时候,如果您无法重组以并行计算很多东西,那么单个矢量可能会获得次要的好处。如果源数据不连续,_mm_setr_ps()
可能会变慢。
已经有多个用于SIMD的C ++包装器库,例如Agner Fog's GPL-licensed VectorClass等。