std :: vectorがアライメントされたメモリを割り当てるための最新のアプローチ


11

次の質問には答えが古いしかし、関連、およびユーザーからのコメントされたマルク・Glisseは十分に議論されていない可能性があり、この問題に対する17 ++ C以来の新たなアプローチがあることを示唆しています。

すべてのデータにアクセスしながら、SIMDでアライメントされたメモリを適切に動作させようとしています。

Intelでは、タイプのfloatベクトルを作成し__m256、サイズを8分の1に削減すると、メモリが整列されます。

例えば std::vector<__m256> mvec_a((N*M)/8);

少しハックな方法で、ベクトル要素へのポインタを浮動小数点にキャストできます。これにより、個々の浮動小数点値にアクセスできます。

代わりに、私std::vector<float>はを正しく調整して、__m256segfaultingなしで他のSIMDタイプにロードできるようにしたいと思います。

私はaligned_allocを調べてきました

これにより、正しく整列されたCスタイルの配列が得られます。

auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));

ただし、これをどのように行うかわかりませんstd::vector<float>。のstd::vector<float>所有権を与えるmarr_a ことは可能はないようです

カスタムアロケーターを作成する必要があるという提案をいくつか見ましたが、これは多くの作業のように思われ、おそらく最新のC ++にはもっと良い方法がありますか?


1
segfaultingなし ...またはを使用し_mm256_loadu_ps(&vec[i])た場合のキャッシュライン分割による潜在的な速度低下なし。デフォルトのチューニングオプションで、GCCはなおものの(分割256ビットのロード/ストアを保証しませ整列 vmovups XMM / vinsertf128に。だから、ある使用する利点_mm256_loadを超えるloaduあなたが心配している場合はどのようにGCCにあなたのコードのコンパイル誰か忘れた場合に使用-mtune=...または-march=オプション。)
Peter Cordes

回答:


1

ベクトルを含む標準C ++ライブラリ内のすべてのコンテナーには、コンテナーのアロケーターを指定するオプションのテンプレートパラメーターがあり、独自のものを実装するのはそれほど多くの作業ではありません。

class my_awesome_allocator {
};

std::vector<float, my_awesome_allocator> awesomely_allocated_vector;

アロケータを実装する少しのコードを書く必要がありますが、それはあなたがすでに書いたよりもはるかに多くのコードではないでしょう。C ++ 17より前のサポートが必要ない場合は、allocate ()メソッドとdeallocate()メソッドを実装するだけで十分です。


彼らも専門化する必要がありますallocator_traits
NathanOliver

1
これは、人々がC ++の迷惑なフープを飛び越えてコピー/貼り付けできる例を含む、正解の良い場所かもしれません。(通常の頭の悪いC ++ではなくalloc + copyの代わりにstd :: vectorがインプレースで再割り当てを試行する方法がある場合のボーナスポイント)また、これvector<float, MAA>はと型互換性がないことに注意してくださいvector<float>(そしてこのアロケータなしでコンパイルさ.push_backれたプレーンで実行するものはすべてstd::vector<float>、新しい割り当てを実行し、最小境界整列メモリにコピーできます。また、new / deleteは、aligned_alloc / freeと互換性がありません)
Peter Cordes

1
アロケータから返されたポインタがstd::vectorの配列のベースアドレスとして直接使用されるという保証はないと思います。たとえばstd::vector、割り当てられたメモリへのポインタを1つだけ使用して、値の範囲の前にメモリに終了/容量/アロケータを格納する実装を想像できます。これは、アロケータによって行われた配置を簡単に無効にする可能性があります。
DietmarKühl

1
それを除いてstd::vectorそれを保証します。それはそれを使用するものです。おそらく、C ++標準がここで指定するものを確認する必要があります。
サムVarshavchik

1
>また、専門化する必要がありますallocator_traits-いいえ、専門化していません。必要なのは、対応するアロケーターを実装することだけです。
Andrey Semashev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.