2016-12-01 8 views
10

短い質問は、2つのベクトルをとる関数がある場合です。 1つは入力され、もう1つは出力されます(別名なし)。私はそれらのうちの1つだけを整列させることができますが、どちらを選ぶべきですか?アラインメントされていないロードとアラインされていないストア

より長いバージョンが

void func(size_t n, void *in, void *out) 
{ 
    __m256i *in256 = reinterpret_cast<__m256i *>(in); 
    __m256i *out256 = reinterpret_cast<__m256i *>(out); 
    while (n >= 32) { 
     __m256i data = _mm256_loadu_si256(in256++); 
     // process data 
     _mm256_storeu_si256(out256++, data); 
     n -= 32; 
    } 
    // process the remaining n % 32 bytes; 
} 

、機能を考慮することであるinoutが整列、32バイトである場合、次にvmovdquを使用して代わりにvmovdqaのペナルティはありません。最悪のシナリオは、両方ともアライメントが合わず、4つのロード/ストアの1つがキャッシュライン境界を越えることです。

この場合、ループに入る前に少数の要素を最初に処理することによって、そのうちの1つをキャッシュライン境界に揃えることができます。しかし、問題は私が選ぶべきか?アライメントされていないロードとストアの間で、どちらが悪いですか?

+3

memcpyの実装を見てみましょう。私は普通の方法があると思うが、それはどれであるか忘れる。あなたがやっていることに多分左右されます。アライメントされたロードはキャッシュラインの境界を避けるので、ロード使用のレイテンシのペナルティはありません(ポインタのインクリメントが予測可能な場合はあまり関係ありません。オブジェクトの外で読むことはしばしば安全ですが、記述はそうではないので、クリーンアップループ用の完全スカラーバージョンを避けることができれば、その決定に影響する可能性があります。 –

+0

私はこれまでにいくつかのテストを実行し、少なくとも私がテストしたプロセッサ(Pentium 4、Core 2、Sandy Bridge、Haswell)では、入力ベクトルの位置合わせが出力ベクトルの位置合わせ。あなたのマイレージは異なる場合があります。テストコードがなくなったため、テストをもう一度やり直す気がなく、どんなドキュメントでも指摘する公式のリファレンスはありませんので、私は答えとして投稿するのが快適ではありません。だから代わりにupvoteを持っている! :-) –

+0

@CodyGrayどうもありがとうございます。私はこの問題のいくつかのテストに取り組んできました。これまでのところ、私が知ることができるのは、「それは依存している」ということだけです。 –

答えて

0

ここにはっきりと述べる危険性:「実際のコードと実際のデータの両方でベンチマークする必要がある」以外は「正解」はありません。いずれのバリエーションが速いかは、使用しているCPU、各パッケージで実行している計算量、その他の多くの要因によって大きく異なります。

コメントに記載されているように、非一時的なストアも試してください。あなたがやっている計算が避けられないデータの待ち時間を持っている場合は

__m256i next = _mm256_loadu_si256(in256++); 
for(...){ 
    __m256i data = next; // usually 0 cost 
    next = _mm256_loadu_si256(in256++); 
    // do computations and store data 
} 

、あなたはまた、インターリーブされた2つのパッケージが計算考慮する必要があります。何も時々できヘルプはすなわち、現在のループ内で、次のデータパケットの入力をロードすることです(これは2倍の数のレジスタを使用します)。

関連する問題