2

これら 2 つの異なるモデルのどちらがより効率的でしょうか (スラッシング、プロセッサ キャッシュの使用率、全体的な設計、すべてなどを考慮してください)?

  1. 1 IOCP と X スレッドのスピンアップ (X はコンピューターに搭載されているプロセッサの数)。これは、私の「サーバー」がすべてのリクエストに対して 1 つの IOCP (キュー) しか持たず、それらを処理/処理するための X スレッドがあることを意味します。この設計の効率性について論じている多くの記事を読みました。このモデルでは、IOCP にも関連付けられるリスナーが 1 つあります。パケット/リクエストの同期を維持する方法を理解できたとしましょう。

  2. X IOCP (X はコンピューターに搭載されているプロセッサの数) であり、各 IOCP には 1 つのスレッドがあります。これは、各プロセッサに独自のキューと、それらを処理/処理するための 1 つのスレッドがあることを意味します。このモデルでは、着信接続を処理し、SOCKET を適切な IOCP (作成された X の 1 つ) に割り当てる別のリスナー (IOCP を使用しない) を用意します。負荷分散を理解できたとしましょう。

2 つの設計 (銀行) の非常に単純化された類推を使用すると、次のようになります。

  1. トランザクションを処理するための複数のレジ係を含む 1 つの行。各人が同じ列に並び、各レジ係が次に空いている人を順番に受け取ります。

  2. 各レジ係には独自の列があり、人々はそれらの列の1つに「配置」されます

これら 2 つの設計のうち、どちらがより効率的か。各モデルでは、オーバーラップされた I/O 構造は (「新規」ではなく) MEM_COMMIT で VirtualAlloc を使用するため、スワップ ファイルは問題になりません (ページングなし)。MEM_COMMIT で VirtualAlloc を使用して説明した方法に基づいて、メモリは予約され、ページアウトされません。これにより、SOCKET は中間層を経由せずに受信データをバッファに直接書き込むことができます。したがって、スラッシングが要因になるべきではないと思いますが、間違っている可能性があります。

#2 の方が効率的だという人もいましたが、このモデルは聞いたことがありません。コメントありがとうございます!

4

2 に答える 2

2

#2の場合、ソケットが受け入れられた時点での「良さ」の測定に基づいて「最良」であると判断したIOCPにソケットを手動で関連付けることを計画していると思いますか?そして、どういうわけか、この「良さ」の尺度は、ソケットの寿命の間持続しますか?

IOCPが「標準」の方法、つまりオプション番号1を使用すると、カーネルは、使用しているスレッドを最適に使用する方法を見つけ出し、スレッドのいずれかがブロックされた場合にさらに実行できるようにします。あなたの方法では、どういうわけか作業を分散する方法を考え出すと仮定すると、オプション1よりも多くのスレッドが実行されることになります。

#2オプションはAcceptEx()、オーバーラップされた受け入れに使用することも防ぎます。これは、シーンからスレッド(および結果として生じるコンテキスト切り替えと潜在的な競合)を削除するときに、通常の受け入れループを使用するよりも効率的です。

あなたのアナロジーは崩壊します。実際には、X銀行の出納係がキューに参加するキューが1つあり、各出納係が独自のキューを持っていて、参加しているキューを推測する必要があるのではなく、効率的な順序で表示されることがわかっている場合です。新しい口座を開設したい人がたくさん含まれているわけではなく、隣の人には支払いをしたいだけの人がたくさん含まれています。単一のキューにより、効率的に処理できます。

私はあなたがについて混乱していると思いますMEM_COMMIT。メモリがページングファイルになく、ページングされないという意味ではありません。オーバーラップバッファを使用する通常の理由はVirtualAlloc、ページ境界での配置を確保し、I / Oのためにロックされるページの数を減らすことです(ページサイズのバッファはページ境界に割り当てることができるため、発生するのではなく1ページだけを取得します)メモリマネージャがページ境界で開始しないブロックを使用することを決定したため、2つにまたがる)。

一般的に、あなたは予定よりも早く何かを最適化しようとしていると思います。最初に通常の方法でIOCPを使用して動作する効率的なサーバーを取得してから、プロファイルを作成します。#2バージョンの構築について心配する必要があるのではないかと真剣に疑っています...同様に、最初にバッファを割り当ててから、サーバーに障害が発生した場合newの複雑さに切り替えます。これは、I / Oロックされたページ制限が原因であり、非ページプールが不足していないことを確認してください(「割り当て粒度」サイズのチャンクを?に割り当てる必要があることに気づきます)。VirtualAlloc()ENOBUFSVirtualAlloc()

とにかく、私はここで利用できる無料のIOCPサーバーフレームワークを持っています:http ://www.serverframework.com/products---the-free-framework.htmlこれはあなたが始めるのに役立つかもしれません。

編集:提案する複雑なバージョンは、NICチーミングを使用して、スイッチが複数のNICにトラフィックを吐き出し、各NICを異なる物理プロセッサにバインドしてから、IOCPスレッドを同じプロセッサにバインドする一部のNUMAアーキテクチャで役立つ可能性があります。次に、そのNUMAノードからメモリを割り当て、ネットワークスイッチにNUMAノード間の接続の負荷分散を効果的に行わせます。IMHOは、最初にIOCPを使用する「通常の」方法を使用してプロファイリングできる動作中のサーバーを取得し、NUMAノード間の問題が実際にパフォーマンスに影響を与えていることがわかった場合にのみ、より複雑なサーバーに移行することをお勧めします。建築...

于 2011-02-12T16:55:26.367 に答える
0

待ち行列理論によると、単一の待ち行列は複数の待ち行列よりも優れた特性を持っています。これは、ワークスティーリングで回避できる可能性があります。

複数のキューを使用する方法では、キャッシュの動作が改善されるはずです。大幅に改善されるかどうかは、単一のトランザクションに関連する受信パケットの数によって異なります。リクエストが 1 つの受信パケットに収まる場合、単一の IOCP アプローチでも単一のスレッドに関連付けられます。

于 2011-02-12T16:25:31.023 に答える