2009-03-05 1 views
10

DDR3デュアルチャネルメモリを搭載したCore 2プロセッサの理論的な最大メモリ帯域幅は印象的です。アーキテクチャ上のWikipedia articleによれば、1秒あたり10+または20+ギガバイトです。しかし、ストックmemcpy()呼び出しはこれを達成しません。おそらく、これはプロセッサの特性に基づいてすべてのプロセッサラインに対してmemcpy()を調整する必要があるOSベンダーの要件に起因するので、ストックmemcpy()の実装幅広い数のブランドとラインで合理的でなければなりません。Core 2またはCore i7アーキテクチャのmemcpy/memmoveを完全に最適化しましたか?

私の質問:Cプログラムで利用できるCore 2またはCore i7プロセッサ用に、自由に利用できる高度にチューニングされたバージョンがありますか?私は、私が自分を必要としている唯一の人ではないと確信しています。そして、みんなが自分のmemcpy()を最適化するための努力の大きな無駄でしょう。

答えて

6

MSVCに/ ARCH:SSE2を指定すると、チューニングされたmemcpyが提供されるはずです(少なくとも、mine does)。

SSEの整列されたロード/ストア組み込み関数を使用して、大規模なチャンクでメモリをコピーし、ダフのデバイスを使用してデータの先頭と末尾を処理し、優れたパフォーマンスを得るには、キャッシュ管理組み込み関数も使用する必要があります。

制限要因は、おそらくCPUサイクルではなくキャッシュミスとサウスブリッジ帯域幅です。メモリバスには常に他のトラフィックがたくさんあるので、通常、このような操作では理論上のメモリ帯域幅のスループットの約90%に達します。

+1

これらの条件が満たされると、MSVC memcpyはベクトル化されます(大体私はこれに関する熟練者ではありません)。ソースアドレスと宛先アドレスは少なくとも8バイト(64ビット)で整列されており、一定の閾値。 64ビットアラインメントは、MSVCが独自の 'malloc'が64ビットアライメントを返すという保証から来ています。次に、32ビットビルドでは、必要に応じて64ビットシャッフルで128ビットSSE2が使用され、64ビットビルドでは、64ビット汎用レジスタ(Duffのデバイス付き)を使用して移動が行われますSSE2に比べると「十分に速い」ため、正しく実行されているからです。 – rwong

+1

/アーチ:最小CPUアーキテクチャの要件の1: SSE2 - 有効SSE2で使用可能な命令の使用を可能にする(デフォルト)のCPU これは視覚的なスタジオvs2013.update3のVC++出力。/ARCH:SSE2はmemcpyのパフォーマンスを改善しません。また、/ ARCH:AVXはベンチマークしましたが、memcpyのパフォーマンスは向上しません。 – zhaorufei

2

あなた自身で書くことができます。 intel optimising compilerを使用してアーキテクチャを直接対象にしてください。

また、インテルは、アプリケーションを最適化するためにVTune(コンパイラと言語に依存しない)というものを作り出しています。

ここにゲームエンジンを最適化するためのarticleがあります。

+0

インテルのコンパイラはどれくらい改善されていますか? –

+0

前回私はそれを試しましたが、約35%でしたが、それは数年前です。 – Crashworks

+0

コメントを残してください。ありがとう。 –

7

memcpyは読み取りと書き込みの両方を考慮して帯域幅を測定しましたので、実際には3GB/sのコピーされたメモリは6GB/sの帯域幅ですか?

帯域幅は理論上最大値であることを覚えておいてください。実際の使用ははるかに低くなります。たとえば、1ページフォルトと帯域幅がMB/sに低下します。

memcpy/memmoveはコンパイラ組み込み関数であり、通常はrep movsd(またはコンパイラがターゲットとする場合は適切なSSE命令)にインライン展開されます。現代のCPUがこのようなrep命令を非常にうまく処理するので、これ以上のコードジェンを改善することは不可能かもしれません。

関連する問題