短い質問は、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;
}
、機能を考慮することであるin
とout
が整列、32バイトである場合、次にvmovdqu
を使用して代わりにvmovdqa
のペナルティはありません。最悪のシナリオは、両方ともアライメントが合わず、4つのロード/ストアの1つがキャッシュライン境界を越えることです。
この場合、ループに入る前に少数の要素を最初に処理することによって、そのうちの1つをキャッシュライン境界に揃えることができます。しかし、問題は私が選ぶべきか?アライメントされていないロードとストアの間で、どちらが悪いですか?
memcpyの実装を見てみましょう。私は普通の方法があると思うが、それはどれであるか忘れる。あなたがやっていることに多分左右されます。アライメントされたロードはキャッシュラインの境界を避けるので、ロード使用のレイテンシのペナルティはありません(ポインタのインクリメントが予測可能な場合はあまり関係ありません。オブジェクトの外で読むことはしばしば安全ですが、記述はそうではないので、クリーンアップループ用の完全スカラーバージョンを避けることができれば、その決定に影響する可能性があります。 –
私はこれまでにいくつかのテストを実行し、少なくとも私がテストしたプロセッサ(Pentium 4、Core 2、Sandy Bridge、Haswell)では、入力ベクトルの位置合わせが出力ベクトルの位置合わせ。あなたのマイレージは異なる場合があります。テストコードがなくなったため、テストをもう一度やり直す気がなく、どんなドキュメントでも指摘する公式のリファレンスはありませんので、私は答えとして投稿するのが快適ではありません。だから代わりにupvoteを持っている! :-) –
@CodyGrayどうもありがとうございます。私はこの問題のいくつかのテストに取り組んできました。これまでのところ、私が知ることができるのは、「それは依存している」ということだけです。 –