2016-08-25 11 views
2

私はmemcpyのSSE4.2バージョンを実装しましたが、Xeon V3では_intel_fast_memcpyを上回らないようです。私はデータが各場所で4から15バイトの間で変化する収集ルーチンで自分のルーチンを使用します。私はここで多くの記事を見てきました。私が見なければならない良い出所は何ですか?_intel_fast_memcpyよりも勝るベクトル化されたmemcpy?

+4

シリコンの設計者がアクセスできるエンジニアが書いた最適化されたルーチンを打ち負かすことができると私は理解しています。 –

+0

また、すべての場所のすべてのデータを16バイトに塗りつぶすだけであれば、memcpyはすべての場所で16バイトの固定コピーになります。長さをチェックしたり、アラインされていないアクセスを使用する必要はありません。 –

+0

memcpyに戻ると、ブランチターゲットとブランチターゲット間のバイト数などの明白でないもの、または命令のアライメントが分岐予測やiキャッシュヒット率に影響する可能性があります。コードを正確にコピーし、調整を開始して、パフォーマンスが低下する場所を確認してください。 –

答えて

1

16Bロードとストアでギャザーを行い、多くのガベージバイトが最後に重なってもかまいませんか?

// pseudocode: pretend these intrinsics take void* args, not float 
char *dst = something; 
__m128 tmp = _mm_loadu_ps(src1); 
_mm_storeu_ps(dst, tmp); 
dst += src1_size; 

tmp = _mm_loadu_ps(src2); 
_mm_storeu_ps(dst, tmp); 
dst += src2_size; 

... 

重複店舗が効率的である(とL1キャッシュはうまくそれらを浸す)、そして現代のCPUが良く、これを処理する必要があります。アラインされていないロード/ストアは、私があなたがこれを打つことができるとは思わないほど安価です。 (ページ分割ロードの平均量を想定していますが、キャッシュライン分割負荷の平均以上の量があっても問題はないでしょう)。

これは、コピーストラテジやマスク生成などを決定する内部ループ。最後のコピーが4Bのみであると思われる場合は、収集バッファーの最後に余分に最大12Bか何かが必要です。 (収集している要素が、ページの最後の16B以内にならないようにする必要があります。次のページはマップされていないか、または読み込み不可能です)

収集している要素の最後を過ぎて読み取るのは問題が発生すると、実際には負荷のためにvpmaskmovが良いアイデアになるでしょう。あなたの要素が4Bで整列されていれば、終わりから3バイトまで読むことができます。 dstバッファには通常の16Bベクトルストアを使用できます。 movupsmovupdまたはmovdquより1バイト短いですが、同じことを行う(Agner Fog's microarch pdfを参照してください、とタグウィキ内の他のリンクため


私は_ps負荷を使用していました。(打ち鳴らすでも時々_mm_store_si128ためmovaps/movupsを使用します。 。)


再:あなたのコメント:レガシーSSE maskmovdquを使用しないでください。最大の問題は、それが唯一のストアとして動作することですので、それはあなたがobj外に読んで回避することはできません。あなたが集めている事柄。 It's slow、それはキャッシュをバイパスします(NTストア)。このデータをリロードすると非常に遅くなります。

AVXのバージョン(vmaskmovvpmaskmov)はそうではないので、コードをmaskmovdquに変換することはおそらく大きな減速になります。


関連:私は約using vmovmaskps for the end of unaligned buffersしばらく前にQ & Aを掲載しました。私はいくつか興味深い反応を得た。マスクを生成するための私の(賢いIMO)戦略がかなり効率的だったにもかかわらず、通常、どのような問題も解決するのに最適な方法ではないことは明らかです。

MOVMASKPSは、「現時点では良いアイデアのように思えました」というものの大部分です。私はそれを使用したことはありません。 - Stephen Canon

関連する問題