【发布时间】:2010-11-16 01:38:10
【问题描述】:
我有这个函数,它使用 SSE2 将一些值加在一起,它应该将 lhs 和 rhs 加在一起并将结果存储回 lhs:
template<typename T>
void simdAdd(T *lhs,T *rhs)
{
asm volatile("movups %0,%%xmm0"::"m"(lhs));
asm volatile("movups %0,%%xmm1"::"m"(rhs));
switch(sizeof(T))
{
case sizeof(uint8_t):
asm volatile("paddb %%xmm0,%%xmm1":);
break;
case sizeof(uint16_t):
asm volatile("paddw %%xmm0,%%xmm1":);
break;
case sizeof(float):
asm volatile("addps %%xmm0,%%xmm1":);
break;
case sizeof(double):
asm volatile("addpd %%xmm0,%%xmm1":);
break;
default:
std::cout<<"error"<<std::endl;
break;
}
asm volatile("movups %%xmm0,%0":"=m"(lhs));
}
我的代码使用这样的函数:
float *values=new float[4];
float *values2=new float[4];
values[0]=1.0f;
values[1]=2.0f;
values[2]=3.0f;
values[3]=4.0f;
values2[0]=1.0f;
values2[1]=2.0f;
values2[2]=3.0f;
values2[3]=4.0f;
simdAdd(values,values2);
for(uint32_t count=0;count<4;count++) std::cout<<values[count]<<std::endl;
但这不起作用,因为当代码运行时它输出 1,2,3,4 而不是 2,4,6,8
【问题讨论】:
-
必须保护内联汇编免受本机 C++ 代码的影响。您的每个块 asm volatile () 都受到保护。不能保证加载在一个块中的寄存器仍将包含下一个块中的值。此外,(load add store) 的执行时间比简单地在本机 c++ 代码中添加值需要更长的时间。在许多情况下,在新硬件上,指令将使用与 SSE 指令相同的标量浮点数运算管道同时执行。使用内联汇编确实没有意义。在需要时使用内部函数。
标签: c++ gcc inline-assembly sse2