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行でエラーが発生します。

オリジナルは_aligned_malloc(...、16);を使用して割り当てられます。同様に関数に渡されるので、sseについての私の理解では、それが整列されていないということではありません。

理由がわからないので、なぜこれがクラッシュするのか誰かがわかるのだろうか。

編集:幅と列は常に4の倍数です。列は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)
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

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);
}
于 2010-08-03T08:30:15.227 に答える