如果浮点值是16字节对齐的,是否可以将其直接转换为__m128
Is it possible to cast floats directly to __m128 if they are 16 byte aligned?
如果浮点是16字节对齐的,那么直接将其强制转换为__m128
是否安全/可能/可取?
我注意到使用_mm_load_ps
和_mm_store_ps
来"包装"原始数组会增加大量开销。
我应该注意哪些潜在的陷阱?
编辑:
实际上,在使用加载和存储指令时没有开销,我混合了一些数字,这就是为什么我得到了更好的性能。即使是你,我也能在__m128
实例中对原始内存地址进行一些可怕的篡改,当我运行测试时,在没有_mm_load_ps
指令的情况下,它需要两倍的时间才能完成,可能会回到某种故障安全代码路径。
是什么让您认为_mm_load_ps
和_mm_store_ps
"增加了显著的开销"?这是将浮点数据加载到SSE寄存器/从SSE寄存器存储浮点数据的正常方式,假设源/目标是内存(任何其他方法最终都会归结为此)。
有几种方法可以将float
值放入SSE寄存器;可以使用以下内部函数:
__m128 sseval;
float a, b, c, d;
sseval = _mm_set_ps(a, b, c, d); // make vector from [ a, b, c, d ]
sseval = _mm_setr_ps(a, b, c, d); // make vector from [ d, c, b, a ]
sseval = _mm_load_ps(&a); // ill-specified here - "a" not float[] ...
// same as _mm_set_ps(a[0], a[1], a[2], a[3])
// if you have an actual array
sseval = _mm_set1_ps(a); // make vector from [ a, a, a, a ]
sseval = _mm_load1_ps(&a); // load from &a, replicate - same as previous
sseval = _mm_set_ss(a); // make vector from [ a, 0, 0, 0 ]
sseval = _mm_load_ss(&a); // load from &a, zero others - same as prev
无论您是声明_mm_set_ss(val)
还是声明_mm_load_ss(&val)
,编译器通常都会创建相同的指令——请尝试并反汇编代码。
在某些情况下,写_mm_set_ss(*valptr)
而不是_mm_load_ss(valptr)
可能是有利的。。。取决于代码的结构。
经过http://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx,这是可能的,但不安全或不推荐。
不应直接访问__m128字段。
原因如下:
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/766c8ddc-2e83-46f0-b5a1-31acbb6ac2c5/
- 将浮子*铸造到__m128将不起作用。C++编译器将__m128类型的赋值转换为SSE指令,将4个浮点数加载到SSE寄存器。假设这个转换是编译的,它不会创建工作代码,因为SEE加载指令并没有生成
__m128变量实际上不是变量或数组。这是SSE寄存器的占位符,由C++编译器替换为SSE汇编指令。要更好地理解这一点,请阅读《英特尔汇编编程参考》。
自从提出这个问题以来,几年过去了。为了回答这个问题,我的经验表明:
是
reinterpret_cast
——只要float*
是16字节对齐的,就可以将float*
转换为__m128*
,反之亦然——示例(在MSVC 2012中):
__declspec( align( 16 ) ) float f[4];
return _mm_mul_ps( _mm_set_ps1( 1.f ), *reinterpret_cast<__m128*>( f ) );
我能看到的明显问题是,你比别名(通过多个指针类型引用内存位置)更容易混淆优化器。混叠的典型问题是,由于优化器没有观察到您正在通过原始指针修改内存位置,因此它认为它是不变的。
由于你显然没有充分使用优化器(或者你愿意依靠它来发出正确的SSE指令),你可能会没事的。
自己使用内部函数的问题是,它们被设计为在SSE寄存器上操作,不能使用从内存位置加载并在单个指令中处理的指令变体。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++