SSE访问冲突

时间:2010-08-03 08:24:34

标签: x86 sse simd

我有代码:

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)

2 个答案:

答案 0 :(得分:3)

我认为你需要使用

__m128 tmp = _mm_load_ps( &original[row * width + col] );

而不是

tmp = (__m128 *)&original[row * width + col];

编辑:如果你获得访问冲突错误是在一些偏移后,那么你的步幅可能没有对齐。无论哪种方式都分配__m128元素(代表4个浮点数)。这样可以保持对齐。

通过消除算术[row * width + col],你也可以获得一些额外的性能。 确定你的步幅并相应地增加你的指针。

答案 1 :(得分:1)

除非tmpwidth具有合适的值,否则

col将会错位。理想情况下,widthcol都应为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);
}