Core 2またはCore i7アーキテクチャ向けに完全に最適化されたmemcpy / memmove?
-
03-07-2019 - |
質問
DDR3デュアルチャネルメモリを搭載したCore 2プロセッサのメモリ帯域幅の理論上の最大値は次のとおりです。アーキテクチャに関するウィキペディアの記事、毎秒10ギガバイトまたは20ギガバイト以上。ただし、標準のmemcpy()呼び出しはこれを達成しません。 (3 GB / sは、私がこのようなシステムで見た最高です。)おそらく、これは、memcpy()がプロセッサの特性に基づいてプロセッサラインごとに調整されるというOSベンダーの要件によるものです。多数のブランドとラインで合理的である必要があります。
私の質問:Cプログラムで利用できるCore 2またはCore i7プロセッサー用に、自由に利用できる高度に調整されたバージョンはありますか?私はそれを必要としている唯一の人ではないと確信しており、誰もが自分のmemcpy()を微最適化するのは大きな努力の無駄です。
解決
/ ARCH:SSE2をMSVCに指定すると、調整されたmemcpyが提供されます(少なくとも、私の場合はそうです)。
これに失敗した場合、SSEアライメントロード/ストアコンパイラ組み込み関数を使用してメモリを大きなチャンクにコピーし、必要に応じてDuff's Device of word readを使用して、データの先頭と末尾を処理してアライメントされた境界に移動します。優れたパフォーマンスを得るには、キャッシュ管理組み込み関数も使用する必要があります。
制限要因は、おそらくCPUサイクルではなく、キャッシュミスとサウスブリッジ帯域幅です。メモリバスには常に他の多くのトラフィックが存在することを考えると、通常、このような操作で理論上のメモリ帯域幅スループットの約90%に達することができてうれしいです。
他のヒント
帯域幅を測定する際、memcpyは読み取りと書き込みの両方を考慮したので、コピーされた3 GB /秒のメモリは実際には6 GB /秒の帯域幅ですか?
帯域幅は理論上の最大値であることに注意してください-実際の使用ははるかに低くなります。たとえば、1ページのフォールトと帯域幅はMB / sに低下します。
memcpy / memmoveはコンパイラ組み込み関数であり、通常、rep movsd(またはコンパイラがそれをターゲットにできる場合は適切なSSE命令)にインライン化されます。最近のCPUはこのようなrep命令を非常にうまく処理するため、これよりもコード生成を改善することは不可能かもしれません。
自分で書くこともできます。 インテル最適化コンパイラを使用して直接アーキテクチャをターゲットにしますか?
Intelは、 VTune (コンパイラーおよび言語に依存しない)アプリケーションの最適化。