8

私は今日、多くのバッファリングされたネットワークアクティビティを実行するプログラムをプロファイリングしていました。このプログラムは、ほとんどの時間をmemcpyで費やし、ライブラリ管理のネットワークバッファと独自の内部バッファの間でデータを移動するだけでした。

これは私に考えさせられました、なぜIntelはRAM自体(またはオフCPUメモリハードウェア)がCPUに触れることなくデータを移動できるようにする「memcpy」命令を持っていないのですか?すべての単語がCPUに完全に到達し、メモリ自体によってすべてが非同期で実行される可能性がある場合は、再度プッシュバックする必要があります。

これが実用的でないアーキテクチャ上の理由はありますか?明らかに、コピーが物理メモリと仮想メモリの間にある場合もありますが、これらのケースは最近RAMのコストとともに減少しています。また、プロセッサがコピーの終了を待って結果を使用できるようになることもありますが、常にそうとは限りません。

4

3 に答える 3

3

これはネットワークスタックの効率を含む大きな問題ですが、私はあなたの具体的な指示の質問に固執します。あなたが提案するのは、「rep mov」を使用して現在利用可能な同期ブロッキングmemcpyではなく、非同期の非ブロッキングコピー命令です。

いくつかのアーキテクチャ上および実用上の問題:

1)非ブロッキングmemcpyは、対応するオペレーティングシステムプロセスとは潜在的に異なるライフタイムを持つ、コピーエンジンなどの物理リソースを消費する必要があります。これはOSにとって非常に厄介です。コンテキストがスレッドBに切り替わる直前にスレッドAがmemcpyをキックするとします。スレッドBもmemcpyを実行したいと考えており、Aよりもはるかに優先度が高くなっています。スレッドAのmemcpyが終了するのを待つ必要がありますか?Aのmemcpyが1000GBの長さだった場合はどうなりますか?コアでより多くのコピーエンジンを提供することは延期しますが、問題を解決しません。基本的に、これはOSのタイムクォンタムとスケジューリングの従来の役割を打ち破ります。

2)ほとんどの命令のように一般的であるために、他のプロセスが何をしたか、またはこれから行うかに関係なく、どのコードでもいつでもmemcpy命令を発行できます。コアには、一度に実行中の非同期memcpy操作の数にある程度の制限が必要です。そのため、次のプロセスが実行されると、memcpyは任意の長いバックログの最後にある可能性があります。非同期コピーには決定論がなく、開発者は単に昔ながらの同期コピーにフォールバックします。

3)キャッシュの局所性は、パフォーマンスに一次的な影響を及ぼします。すでにL1キャッシュにあるバッファーの従来のコピーは、少なくとも宛先バッファーがコアのL1のローカルのままであるため、非常に高速で比較的電力効率が高くなります。ネットワークコピーの場合、カーネルからユーザーバッファーへのコピーは、ユーザーバッファーをアプリケーションに渡す直前に行われます。そのため、アプリケーションはL1ヒットと優れた効率を享受しています。非同期memcpyエンジンがコア以外の場所に存在する場合、コピー操作によってラインがコアから引き離され(スヌープ)、アプリケーションキャッシュミスが発生します。ネットシステムの効率は、おそらく今日よりもはるかに悪いでしょう。

4)非同期memcpy命令は、コピーが完了したかどうかを確認するために後で使用するために、コピーを識別するある種のトークンを返す必要があります(別の命令が必要です)。トークンが与えられると、コアはその特定の保留中または実行中のコピーに関してある種の複雑なコンテキストルックアップを実行する必要があります-これらの種類の操作はコアマイクロコードよりもソフトウェアによってより適切に処理されます。OSがプロセスを強制終了し、実行中および保留中のすべてのmemcpy操作をモップアップする必要がある場合はどうなりますか?OSは、プロセスがその命令を何回使用したか、およびどの対応するトークンがどのプロセスに属しているかをどのように知るのですか?

- - 編集 - -

5)別の問題:コア外のコピーエンジンは、キャッシュするコアの帯域幅と生のコピーパフォーマンスで競合する必要があります。これは非常に高く、外部メモリの帯域幅よりもはるかに高くなります。キャッシュミスの場合、メモリサブシステムは同期と非同期の両方のmemcpyを等しくボトルネックにします。少なくとも一部のデータがキャッシュにある場合は、これは良い賭けですが、コアは外部コピーエンジンよりも速くコピーを完了します。

于 2011-08-14T03:45:17.560 に答える
1

ネットウィン?

非同期コピーエンジンの実装が役立つかどうかは明らかではありません。そのようなことの複雑さは、利点を打ち消すかもしれないオーバーヘッドを追加するでしょう、そしてそれはmemcpy()にバインドされているいくつかのプログラムのためだけに価値がないでしょう。

より重いユーザーコンテキスト?

実装には、ユーザーコンテキストまたはコアごとのリソースが含まれます。差し迫った問題の1つは、これは実行時間の長い操作である可能性があるため、割り込みを許可して自動的に再開する必要があることです。

つまり、実装がユーザーコンテキストの一部である場合、すべてのコンテキストスイッチで保存する必要があるより多くの状態を表す、既存の状態をオーバーレイする必要があります。

既存の状態をオーバーレイすることは、文字列移動命令がどのように機能するかを正確に示しています。つまり、パラメータを汎用レジスタに保持します。ただし、既存の状態が消費された場合、この状態は操作中には役に立ちません。文字列移動命令を使用することもできます。これは、メモリコピー機能が実際に機能する方法です。

または遠いカーネルリソース?

ある種のコアごとの状態を使用する場合は、カーネル管理のリソースである必要があります。結果として生じるリング交差のオーバーヘッド(カーネルトラップとリターン)は非常に高価であり、利益をさらに制限するか、ペナルティに変えます。

アイディア!その超高速CPUのことをやってもらいましょう!

これを確認する別の方法は、移動結果との一貫性を保つ必要があるキャッシュメモリのすべてのリングの中心に、高度に調整された非常に高速なメモリ移動エンジンがすでに存在することです。そのこと:CPU。プログラムがそれを行う必要がある場合は、その高速で精巧なハードウェアを問題に適用してみませんか?

于 2011-08-14T06:29:13.233 に答える
1

古いPCアーキテクチャでは、メモリからメモリへの転送はDMAコントローラでサポートされていました。現在、他のアーキテクチャ(TI DaVinciやOMAPプロセッサなど)にも同様のサポートがあります。

問題は、多くのシステムでボトルネックになる可能性のあるメモリ帯域幅を消費することです。srkingの回答が示唆するように、データをCPUのキャッシュに読み取り、それをコピーすることで、メモリからメモリへのDMAよりもはるかに効率的になる可能性があります。DMAはバックグラウンドで動作しているように見える場合でも、CPUとのバス競合が発生します。フリーランチはありません。

より良い解決策は、バッファがアプリケーションとドライバ/ハードウェアの間で共有される、ある種のゼロコピーアーキテクチャです。つまり、着信ネットワークデータは事前​​に割り当てられたバッファに直接読み込まれるため、コピーする必要はなく、外部データはアプリケーションのバッファからネットワークハードウェアに直接読み込まれます。私はこれが組み込み/リアルタイムネットワークスタックで行われるのを見てきました。

于 2011-08-14T06:07:06.440 に答える