4

我有代码:

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 行。

original 使用 _aligned_malloc(..., 16); 以及传递给函数,所以就我对 sse 的理解而言,它不应该是不对齐的。

我想知道是否有人可以看到为什么会崩溃,因为我不明白为什么。

编辑:宽度和 col 始终是 4 的倍数。 Col 是 0 或 4,而 width 始终是 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)
4

2 回答 2

4

我认为你需要使用

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

代替

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

编辑:如果您在某个偏移量之后出现访问冲突错误,那么您的步幅可能未对齐。无论哪种方式分配 __m128 个元素(代表 4 个浮点数)。这负责对齐。

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

于 2010-08-03T08:49:29.783 回答
1

tmpwidth除非并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);
}
于 2010-08-03T08:30:15.227 回答