2016-10-01 4 views
1

ベクトルをSSEレジスタにロードしようとしていますが、コードはエラーなしでコンパイルされますが、実行しようとするとセグメント化エラーが発生します。ここでは、私のコードです:ベクトルをSSEレジスタにロードする

inline int SSEJaccard::calcSSEJaccardDist(unsigned int id1, unsigned int id2) { 
    int result; 
    __m128i v, v1; 
    std::vector<uint32_t> &fv1 = fvs[id1]; 
    std::vector<uint32_t> &fv2 = fvs[id2]; 
    v = _mm_load_si128((__m128i const*) (&fv1)); 
    v1 = _mm_load_si128((__m128i const*) (&fv2)); 
    v = _mm_and_si128(v,v1); 
    result =_mm_extract_epi16(v, 0) + _mm_extract_epi16(v, 4); 
return result; 
} 

そして、FSVは、次のように定義されたグローバル変数です:

std::vector<std::vector<uint32_t> > fvs; 

私はインテルコンパイラ(ICC)を使用しています。ありがとうございます

+1

あなたstd::vector sが4つの要素、すなわち(より可能性があり、適切なアライメント与え破棄されます)、十分なデータを持っていることを確認してください。 'fvs'を単一のベクトルにして、独自のインデックスを作成して2D配列をシミュレートします。 [この質問の回答](http://stackoverflow.com/questions/33093860/using-nested-vectors-vs-a-flatten-vector-wrapper-strange-behaviour)を参照してください。異なる行の長さが異なり、別々に成長/縮小することができる「不揃い」の配列が必要な場合にのみ、 'vector > 'を使用してください。 (または、その場で列の数を変更する必要がある場合) –

+0

私は、OPが適切な多次元配列の代わりにポインタの配列を使用していた別の質問への回答を書いたことがわかりましたが、見つけられません。 :/その質問は、ほとんど最悪の場合の条件(非常に小さな割り当てが多い連続したメモリアクセスの代わりに散在する)で配列へのポインタを使用していて、IIRCの修正から10倍以上のスピードアップを得ました。 –

答えて

6

std::vectorへのポインタを組み込み関数に渡していることに注目してください。

代わりに、前記ベクトルに含まれるデータへのポインタを渡す必要があります。

v = _mm_load_si128((__m128i const*) (&(fv1[0]))); 

または

v1 = _mm_load_si128((__m128i const*) (fv2.data()); 

std::vectorオブジェクト自体は単なるポインタと割り当てられた/現在のサイズ情報を保持し、それはSSEの組み込み関数は全く期待するものではありません。これはsegfaultについても説明しているので、sizeof(std::vector)は16バイト未満である可能性があります(私の場合は12を返します)。

アライメントはもちろん、もちろんSSEでも考慮する必要がありますが、賢明なアロケータのトリッキーでstd::vectorに強制することができます。 Here is SO question on that topic

はまた、ベクトルのベクトルは、パフォーマンスのために悪いです

+1

'std :: vector'オブジェクト自体は単にポインタを保持し、/現在のサイズ情報を確保しています。実際のデータを取得することは、オブジェクトの先頭からのオフセットだけでなく、余分な間接的なレベルです。アラインメントに関しては、 'std :: vector'を整列されたアロケーションを使うのは難しいでしょう。 MSVCにはカスタムアロケータでも不可能なバグがあることを思い出しています。したがって、理想的ではありませんが現代のCPUでは遅くない '_mm_loadu_si128'を使うだけでよいでしょう。 –

+0

間接指示で+1良いポイント、私は誤解を招く文章を修正します。私は今MSVC140を試してみましたが、それは動作しているようですが、もちろん一貫性の保証はありません – Ap31

2

整列されたロードとストアを使用する前に、データ構造を整列させる必要があります。私はデフォルトベクトルアロケータがSSE2命令で必要とされる16バイトの境界でアライメントを行うとは思っていません。

関連する問題