3

これは、ベクトルの個々の要素を異なるメモリ位置にファンアウトすること(分散操作)に関して私が持っていた前の質問に便乗します。__m256d私のコードは、「長い間」再びアクセスされない大量のデータをメモリに保存します。非一時的なヒントの指示を使用して、これらすべてのストアによって生成されるキャッシュ汚染の量を減らしたいと思います。しかし、私はこれを行うための良い方法を思い付くことができません。これが私のコードが今どのように見えるかの要約です:

__m256d src = ...  //  data
double *dst;
int dst_dist;

__m128d a = _mm256_extractf128_pd(src, 0);
__m128d b = _mm256_extractf128_pd(src, 1);

_mm_storel_pd(dst + 0*dst_dist, a);
_mm_storeh_pd(dst + 1*dst_dist, a);
_mm_storel_pd(dst + 2*dst_dist, b);
_mm_storeh_pd(dst + 3*dst_dist, b);

非テンポラルヒントを使用して64ビットストアを実行したいのですが、XMMレジスタから直接これを実行する方法はないようです。これを達成するための最良の方法は何でしょうか?

4

2 に答える 2

4

非テンポラル ヒントで部分的なレジスタ ストアを使用しないようにするのには十分な理由があります。多数の小さなデータをまったく関係のないメモリ ロケーションに分散させようとすると、CPU の書き込み結合バッファーがオーバーフローし、キャッシュを介して通常の書き込みが行われます (おそらく追加のパフォーマンス コストがかかります)。

書き込み結合 (非一時的なヒント) を使用する正しい方法は、キャッシュ ライン全体を埋めることです。そのため、通常はデータを結合して完全なレジスタにし、MOVNTDQ で一度に書き込みます。

于 2011-12-10T11:02:14.230 に答える
2

命令を使用して、非テンポラル ヒントを使用して SSE ベクトルの一部を格納できますMASKMOVDQU。セマンティクスはあなたの例に正確にマッピングされていませんが、機能させることができます。ただし、この命令は通常、分岐を避けるためにのみ使用する必要があります (その場合でも、select と通常のストアを使用する方が通常は適切です)。また、格納先のアドレスが命令で暗黙的に指定されているため、使用するのが少し面倒です。

実行している操作は、マトリックス転置 (または 90 度の画像回転) の一部によく似ています。最終的に他のデータを隣接するアドレスに格納しますか? アルゴリズムを変更して、これらのストアをバッチ処理し、代わりに完全なベクトルを書き込む方法はありますか (おそらく、小さなキャッシュ可能なスクラッチ バッファーへの連続した書き込みを使用し、ソフトウェアで書き込み結合を行うことによっても可能です)。

于 2011-12-09T22:07:38.760 に答える