【发布时间】:2016-09-26 07:13:00
【问题描述】:
我正在尝试使用 SSE 进行一些添加,并且我正在使用这个 C 和程序集。为什么这样的事情不起作用?
struct vector {
float x1, x2, x3, x4;
};
struct vector *dodawanie(const struct vector v1[], const struct vector v2[], int size) {
struct vector vec[size];
int i;
for(i = 0; i < size; i++) {
asm(
"MOV %1, %%rax \n"
"MOV %2, %%rdx \n"
"MOVUPS (%%rax), %%xmm0 \n"
"MOVUPS (%%rdx), %%xmm1 \n"
"ADDPS %%xmm0, %%xmm1 \n"
"MOVUPS %%xmm1, %0 \n"
:"=g"(vec[i]) //wyjscie
:"g"(v1[i]), "g"(v2[i]) //wejscie
:"%rax", "%rdx"
);
}
return vec;
}
我收到错误:线程 1:EXC_BAD_ACCESS (CODE = EXC_I386_GPFLT)
但是当我把 v1[i], v2[i] 替换为 v1, v2 等时,这可以正常工作,但当然只适用于数组的第一个元素.
我的代码有什么问题?
【问题讨论】:
-
1.看看生成的 asm 可能会发生 %1 和 %2 正在被
rax/rdx传递。 2.尝试通过rax和rdx直接传递%1和%2。看这里:gcc.gnu.org/onlinedocs/gcc/… 用于 x86 特定约束 -
首先我倾向于为
addps使用编译器内在函数。如果您打算使用内联汇编器,我会遵循 Michal 的建议,即着眼于获取汇编器模板来完成大部分工作。假设 v1、v2 和 vec 都是向量数组 (__m128),那么这样的事情可能会起作用asm( "MOVAPS %[v1], %[out]\n\t" "ADDPS %[v2], %[out]\n\t" :[out]"=&x,m"(vec[i]) :[v1]"mx,x"(v1[i]), [v2]"mx,x"(v2[i]) ); -
您的代码似乎正在返回一个指向局部变量的指针,这可能会导致一些意外行为,因为您依赖于在函数返回后和使用数据之前堆栈不会被丢弃。
标签: c arrays x86-64 sse inline-assembly