我正在为一个项目使用GCC SIMD向量扩展,一切工作得相当顺利,但是转换操作会重置向量的所有分量。
手册指出:
可以从一个向量类型转换到另一个向量类型,前提是它们具有相同的大小(事实上,您还可以将向量与具有相同大小的其他数据类型进行转换)。
以下是一个简单的示例:
#include <stdio.h>
typedef int int4 __attribute__ (( vector_size( sizeof( int ) * 4 ) ));
typedef float float4 __attribute__ (( vector_size( sizeof( float ) * 4 ) ));
int main()
{
int4 i = { 1 , 2 , 3 , 4 };
float4 f = { 0.1 , 0.2 , 0.3 , 0.4 };
printf( "%i %i %i %i\n" , i[0] , i[1] , i[2] , i[3] );
printf( "%f %f %f %f\n" , f[0] , f[1] , f[2] , f[3] );
f = ( float4 )i;
printf( "%f %f %f %f\n" , f[0] , f[1] , f[2] , f[3] );
}
使用gcc cast.c -O3 -o cast
编译并在我的机器上运行,我得到了以下结果:
1 2 3 4
0.100000 0.200000 0.300000 0.400000
0.000000 0.000000 0.000000 0.000000 <-- no no no
我不是汇编大师,但我在这里看到了一些字节移动:
[...] 400454: f2 0f 10 1d 1c 02 00 movsd 0x21c(%rip),%xmm3 40045b: 00 40045c: bf 49 06 40 00 mov $0x400649,%edi 400461: f2 0f 10 15 17 02 00 movsd 0x217(%rip),%xmm2 400468: 00 400469: b8 04 00 00 00 mov $0x4,%eax 40046e: f2 0f 10 0d 12 02 00 movsd 0x212(%rip),%xmm1 400475: 00 400476: f2 0f 10 05 12 02 00 movsd 0x212(%rip),%xmm0 40047d: 00 40047e: 48 83 c4 08 add $0x8,%rsp 400482: e9 59 ff ff ff jmpq 4003e0我怀疑这个标量的向量等效物:
*( int * )&float_value = int_value;
你怎么解释这种行为?
_mm_cvtepi32_ps
(当然,这会破坏您的向量代码的良好架构独立性,这也很烦人;一种常见的方法是使用一个翻译头文件,定义一个可移植的“内置函数”集)。 - Stephen Canon_mm_cvtepi32_ps((__m128i)x)
。 - Stephen Canon