我有代码:
float *mu_x_ptr;
__m128 *tmp;
__m128 *mm_mu_x;
mu_x_ptr = _aligned_malloc(4*sizeof(float), 16);
mm_mu_x = (__m128*) mu_x_ptr;
for(row = 0; row < ker_size; row++) {
tmp = (__m128*) &original[row*width + col];
*mm_mu_x = _mm_add_ps(*tmp, *mm_mu_x);
}
从此我得到:
First-chance exception at 0x00ad192e in SSIM.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x00ad192e in SSIM.exe: 0xC0000005: Access violation reading location 0x00000000.
The program '[4452] SSIM.exe: Native' has exited with code -1073741819 (0xc0000005)
运行程序时,错误发生在_mm_add_ps行。
原始分配使用_aligned_malloc(...,16);同样也传递给函数,所以就我对sse的理解而言,它不应该是它不是全部签名。
我想知道是否有人能看出为什么会崩溃,因为我看不出原因。
编辑:宽度和col始终为4的倍数.Col为0或4,而宽度始终为4的倍数。
EDIT2:看起来我的原始阵列没有对齐。不会:
function(float *original);
.
.
.
orignal = _aligned_malloc(width*height*sizeof(float), 16);
function(original);
_aligned_free(original);
}
确保原稿在功能内部对齐吗?
Edit3:这实际上很奇怪。当我这样做时:
float *orig;
orig = _aligned_malloc(width*height*sizeof(float), 16);
assert(isAligned(orig));
断言以
失败#define isAligned(p) (((unsigned long)(p)) & 15 == 0)
答案 0 :(得分:3)
我认为你需要使用
__m128 tmp = _mm_load_ps( &original[row * width + col] );
而不是
tmp = (__m128 *)&original[row * width + col];
编辑:如果你获得访问冲突错误是在一些偏移后,那么你的步幅可能没有对齐。无论哪种方式都分配__m128元素(代表4个浮点数)。这样可以保持对齐。
通过消除算术[row * width + col],你也可以获得一些额外的性能。 确定你的步幅并相应地增加你的指针。
答案 1 :(得分:1)
tmp
和width
具有合适的值,否则 col
将会错位。理想情况下,width
和col
都应为4的倍数。
您可能需要添加一些断言来检查对齐,例如
#define IsAligned(p) ((((unsigned long)(p)) & 15) == 0)
float *mu_x_ptr;
__m128 *tmp;
__m128 *mm_mu_x;
assert(original != NULL && IsAligned(original));
mu_x_ptr = _aligned_malloc(4 * sizeof(float), 16);
assert(mu_x_ptr != NULL && IsAligned(mu_x_ptr));
mm_mu_x = (__m128 *)mu_x_ptr;
assert(IsAligned(mm_mu_x));
for (row = 0; row < ker_size; row++)
{
tmp = (__m128 *)&original[row * width + col];
assert(IsAligned(tmp));
*mm_mu_x = _mm_add_ps(*tmp, *mm_mu_x);
}