使用_mm_load_pd时函数崩溃
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用_mm_load_pd时函数崩溃相关的知识,希望对你有一定的参考价值。
我有以下功能:
template <typename T>
void SSE_vectormult(T * A, T * B, int size)
{
__m128d a;
__m128d b;
__m128d c;
double A2[2], B2[2], C[2];
const double * A2ptr, * B2ptr;
A2ptr = &A2[0];
B2ptr = &B2[0];
a = _mm_load_pd(A);
for(int i = 0; i < size; i+=2)
{
std::cout << "In SSE_vectormult: i is: " << i << '
';
A2[0] = A[i];
B2[0] = B[i];
A2[1] = A[i+1];
B2[1] = B[i+1];
std::cout << "Values from A and B written to A2 and B2
";
a = _mm_load_pd(A2ptr);
b = _mm_load_pd(B2ptr);
std::cout << "Values converted to a and b
";
c = _mm_mul_pd(a,b);
_mm_store_pd(C, c);
A[i] = C[0];
A[i+1] = C[1];
};
// const int mask = 0xf1;
// __m128d res = _mm_dp_pd(a,b,mask);
// r1 = _mm_mul_pd(a, b);
// r2 = _mm_hadd_pd(r1, r1);
// c = _mm_hadd_pd(r2, r2);
// c = _mm_scale_pd(a, b);
// _mm_store_pd(A, c);
}
当我在Linux上调用它时,一切都很好,但是当我在Windows操作系统上调用它时,我的程序崩溃了“程序不再工作”。我做错了什么,如何确定我的错误?
您的数据不保证按SSE加载的要求对齐16字节。要么使用_mm_loadu_pd
:
a = _mm_loadu_pd(A);
...
a = _mm_loadu_pd(A2ptr);
b = _mm_loadu_pd(B2ptr);
或确保您的数据在可能的情况下正确对齐,例如:对于静态或本地人:
alignas(16) double A2[2], B2[2], C[2]; // C++11, or C11 with <stdalign.h>
或者没有C ++ 11,使用特定于编译器的语言扩展:
__attribute__ ((aligned(16))) double A2[2], B2[2], C[2]; // gcc/clang/ICC/et al
__declspec (align(16)) double A2[2], B2[2], C[2]; // MSVC
你可以使用#ifdef
来#define
和一个适用于目标编译器的ALIGN(x)
宏。
让我试着回答为什么你的代码在Linux而不是Windows中工作。以64位模式编译的代码使堆栈对齐16个字节。但是,以32位模式编译的代码在Windows上只对齐4字节,并且不保证在Linux上对齐16字节。
GCC在64位系统上默认为64位模式。但是,即使在64位系统上,MSVC也默认为32位模式。所以我猜你没有在Windows中以64位模式编译代码,_mm_load_pd
和_mm_store_pd
都需要16字节对齐的地址,所以代码崩溃了。
您至少有三种不同的解决方案可以让您的代码在Windows中运行。
- 以64位模式编译代码。
- 使用未对齐的载荷和存储(例如
_mm_storeu_pd
) - 像Paul R建议的那样,自己对齐数据。
最好的解决方案是第三种解决方案,从那时起,您的代码将在32位系统上运行,而在较旧的系统上,未对齐的加载/存储速度要慢得多。
如果你看一下http://msdn.microsoft.com/en-us/library/cww3b12t(v=vs.90).aspx,你可以看到函数__mm_load_pd被定义为:
__m128d _mm_load_pd (double *p);
因此,在您的代码中,A应该是double类型,但是A是tipe T,它是模板参数。您应该确保使用权限模板params调用SSE_vectormult函数,或者只是删除模板并使用double类型,
以上是关于使用_mm_load_pd时函数崩溃的主要内容,如果未能解决你的问题,请参考以下文章