我尝试使用Intel Intrinsics在float
阵列上快速执行操作。这些行动本身似乎运作良好;但是,当我尝试将操作结果转换为标准C变量时,我得到一个SEGFAULT。如果我评论下面指出的行,程序就会运行。如果我保存指示行的结果,但不以任何方式操作它,程序运行正常。只有当我尝试(以任何方式)与_mm_cvtss_f32(C)
的结果进行交互时,程序才会崩溃。有什么想法吗?
float proc(float *a, float *b, int n, int c, int width) {
// Operation: SUM: (A - B) ^ 2
__m128 A, B, C;
float total = 0;
for (int d = 0, k = 0; k < c; d += width, k++) {
for (int i = 0; i < n / 4 * 4; i += 4) {
A = _mm_load_ps(&a[i + d]);
B = _mm_load_ps(&b[i + d]);
C = _mm_sub_ps(A, B);
C = _mm_mul_ps(C, C);
C = _mm_hadd_ps(C, C);
C = _mm_hadd_ps(C, C);
total += _mm_cvtss_f32(C); // SEGFAULT HERE
}
for (int i = n / 4 * 4; i < n; i++) {
int diff = a[i + d] - b[i + d];
total += diff * diff;
}
}
return total;
}
答案 0 :(得分:0)
你确定你的程序实际上在你引用的指令中崩溃了,或者编译器只是在你删除_mm_cvtss_f32()行(它没有任何其他可见的副作用)时优化其余的循环?由于您使用的是对齐的加载指令,因此潜在的故障原因可能是a和b阵列的不正确对齐。你确定它们是16字节对齐的吗?在当代英特尔硬件上,16字节对齐和未对齐加载之间的性能差异很小(有关该问题的讨论,请参阅上述问题的评论)。
我在原始评论中提到movaps
的编码比movups
短。 这是不正确的。我正在考虑而不是movaps
与movapd
进行相同的内存传输,只是将它们标记为单精度和双精度精确数据,分别。在实践中,他们做同样的事情,但movaps
编码较短。