我使用英特尔内在函数具有以下功能:
int c_lattice_worker( int lm, double* inArr, double* outArr, int arrLen,
double sin_, double cos_ ) {
int xi, yi;
double x, y;
__m128d _msin, _mcos;
__m128d _m0, _m1;
_msin = _mm_loaddup_pd( &sin_ );
_mcos = _mm_loaddup_pd( &cos_ );
for ( int xnc = lm; xnc < (arrLen - (lm << 1)); xnc += 2 ) {
_m0 = _mm_load_pd( &inArr[ xnc ] );
_m1 = _mm_shuffle_pd( _m0, _m0, 0x1 );
_m0 = _mm_mul_pd( _msin, _m0 );
_m1 = _mm_mul_pd( _mcos, _m1 );
_m0 = _mm_addsub_pd( _m0, _m1 );
_mm_store_sd( &outArr[ xnc + 1 ], _m0 ); // segfault here if lm == 1
_m1 = _mm_shuffle_pd( _m0, _m0, 0x1 );
_mm_store_sd( &outArr[ xnc ], _m1 ); // segfault here if lm == 1
}
}
// fliping the lm modifier
return 1 - lm;
}
数组inArr
和outArr
的长度均匀,lm
为0或1.如果为0,则一切正常,但如果lm
为1则{ {1}}导致程序出现段错误(或者换句话说,注释掉这两行都会导致段错误消失)。对于_mm_store_sd
,lm == 1
索引未与16个字节对齐,但根据英特尔的文档,xnc
不需要16字节对齐,仅适用于_mm_store_sd
。我很无能为力。有什么建议吗?
答案 0 :(得分:1)
事实证明:
我可以使用_mm_storeu_pd
将两个打包的64位浮点数存储到未对齐的内存地址中。
但是当我这样做时,我还必须使用_mm_loadu_pd
从未对齐的内存地址加载。
所以实际上_mm_load_pd
导致了段错误,但当我注释掉商店操作时,它已被优化掉,因为它是死代码。