4

重複の可能性:
SSE、組み込み関数、およびアライメント

私はSIMDプログラミングに慣れていないので、明らかな質問をしている場合は失礼します。

私は少し実験していて、動的に割り当てられた構造にSIMD値を格納したいところに到達しました。

コードは次のとおりです。

struct SimdTest
{
    __m128      m_simdVal;

    void setZero()
    {
        __m128 tmp = _mm_setzero_ps(); 
        m_simdVal = tmp; // <<--- CRASH ---
    }
};

TEST( Plane, dynamicallyAllocatedPlane )
{
    SimdTest* test = new SimdTest();

    test->setZero();

    delete test;
}

CRASHコメントでマークされたメソッドを実行すると、次の例外を除いてコードがクラッシュします。

Unhandled exception at 0x775315de in test-core.exe: 0xC0000005: Access violation reading location 0x00000000

誰かが割り当て操作が壊れた理由と、SIMDを含むオブジェクトを動的に割り当てて正常に機能させる方法を説明してもらえますか?

SimdTestオブジェクトを静的にインスタンス化してsetZeroメソッドを呼び出すと、すべてが正常に機能することを追加する必要があります。

ありがとう、パクサス

4

2 に答える 2

5

構造がずれているために死んでしまいます。CRTアロケータは、8、16へのアライメントのみを約束します。ここでは必要です。ヒープに割り当てられたメモリを適切に整列させるには、MSVCで_aligned_malloc()を使用する必要があります。

それについて行く2つの方法。これはPOD構造体であるため、次のようにキャストできます。

#include <malloc.h>
...
    SimdTest* test = (SimdTest*)_aligned_malloc(sizeof SimdTest, 16);
    test->setZero();
    _aligned_free(test);

または、構造体のnew/delete演算子をオーバーライドできます。

struct SimdTest
{
    void* operator new(size_t size) { return _aligned_malloc(size, 16); }
    void operator delete(void* mem) { return _aligned_free(mem); }
    // etc..
};
于 2012-10-03T19:22:11.390 に答える
-1

MSDNによると、_m128は__m128ではなく_m128で16バイトずつ自動的に調整されます。しかし、とにかく、他の人は正しいと思います。2種類の移動命令があることを思い出します。1つは整列されたmovAps用で、もう1つは整列されていないmovUps用です。最初に16bのアラインメントが必要ですが、その他は必要ありません。コンパイラが両方を使用できるかどうかはわかりませんが、私はこの_m128タイプを試しました。

実際には、そのための特別なタイプがあります:_M128A。

于 2012-10-03T17:49:12.967 に答える