2013-02-02 3 views
5

std :: unordered_mapの値として__m128(SSEベクトル)を使用するバグを追跡しました。 これは、mingw32 g ++ 4.7.2でランタイムセグメンテーションフォルトを引き起こします。STL unordered_mapが__m128の値でクラッシュする

下記の例をご覧ください。 これが失敗する理由はありますか? または、回避策がありますか? (私はクラスで値をラップしようとしましたが、それは助けになりませんでした。) ありがとう。

#include <unordered_map> 
#include <xmmintrin.h>   // __m128 
#include <iostream> 

int main() 
{ 
    std::unordered_map<int,__m128> m; 
    std::cerr << "still ok\n"; 
    m[0] = __m128(); 
    std::cerr << "crash in previous statement\n"; 
    return 0; 
} 

コンパイル設定:

ABIは__m128変数が常に上に整列されていることを確認してい: G ++ -march =ネイティブ-std = C++ 11

+1

関連記事を読む:http://stackoverflow.com/questions/4424741/aligned-types-and-passing-arguments-by-value – Joe

+0

'__m128'型へのポインタを使用すると、コンパイラが出力する結果のロード/ストア関数は、通常、さまざまな整列されたものになります。そのため、基底のメモリ型に必要に応じて整列されます(この場合は16バイトの整列)。私は、コンテナコードのどこかで、 '__m128'へのポインタが参照解除されており、アラインメントの仮定が成立せず、セグメンテーション違反が発生していると推測しています。デバッガでプログラムを実行し、クラッシュ後にポインタ値を調べると、これを見ることができます。 –

+0

'm [0]'未定義の動作にアクセスできません。 – hirschhornsalz

答えて

2

現在、C++では、オーバーライドされた型の動的割り当ては処理されません。通常のx86 ABIでは、標準のアライメントは8で、__m128のアライメントは16バイトであるため、オーバーライドされています。通常のx86_64 ABIでは、標準のアラインメントは16で__m128は安全です(しかし、__m256は32バイトアライメントで再び安全ではありません)。

は、物事になるだろう次の標準で可能性の変化のため、この論文は、「ただ働き」を参照してください: 一方http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3396.htm

は、あなたがaligned_alloc(C11)に基づいて、たとえば、独自のアロケータを指定することができ、 posix_memalign(unix)、_aligned_malloc(Microsoft)など

3

アライメントに関する2つの問題があります。スタック?

グローバルnewオペレータは、__m128タイプに対して適切に整列されたメモリを返しますか?すなわち、16バイトのアラインメントを有するメモリを返す。

+2

フィードバックありがとうございます。それは間違いなく位置合わせの問題です。 STLコンテナは、要素のアライメント属性を尊重するように設計する必要があります。おそらくこれはカスタムメモリアロケータが必要でしょうか? – Hugues

関連する問題