2

私は C# 非同期ソケット プログラミングを学んでおり、バイト バッファーをある種のプールで再利用し、ソケットからデータを受信するときに必要に応じてチェックアウトすることをお勧めします。

ただし、バイト配列プールを実行する 2 つの異なる方法を見てきました。1 つは単純なキュー システムを使用し、必要に応じてキューに追加/削除するだけでした。1 つが要求され、キューにそれ以上残っていない場合は、新しいバイト配列が作成されます。

私が見たもう 1 つの方法は、プログラム全体で 1 つの大きなバイト配列を使用します。キューの考え方は引き続き適用されますが、代わりに、使用するバイト配列のスライス (オフセット) を決定する整数のキューです。配列が要求され、キューにそれ以上残っていない場合は、配列のサイズを変更する必要があります。

高度にスケーラブルなサーバーに適したソリューションは次のうちどれですか? 私の本能は、必要に応じて配列のサイズを変更すると(大きなチャンクで割り当てたとしても)、特に配列が大きくなった場合にかなりコストがかかると想像するため、多くのバイト配列を使用する方が安くなるということです。複数の配列を使用することもより直感的なようです-私が考えていない1つの大規模な配列を使用する利点はありますか?

4

5 に答える 5

5

あなたはあなたの腸の感覚が正しいです。配列を大きくする必要があるたびに、配列を再作成し、既存のバイトをコピーします。ここではバイトについて話しているので、配列のサイズはすぐに大きくなる可能性があります。したがって、毎回連続したメモリを要求することになります。これは、プログラムがメモリをどのように使用するかによって、実行可能かどうかによって異なります。これも事実上、いわば仮想プールになります。定義上、プールには、さまざまなクライアントによって管理および共有される複数のアイテムのセットがあります。

ワンアレイソリューションは、実装がはるかに複雑です。良い点は、1つの配列ソリューションを使用すると、可変サイズのチャンクを提供できることですが、これには、mallocを本質的に再実装するという犠牲が伴います。つまり、断片化などに対処する必要があります。

マルチアレイソリューションを使用すると、N個のバッファーでプールを初期化し、それらを簡単に管理できます。間違いなく私がお勧めするアプローチです。

于 2009-02-24T14:43:05.377 に答える
2

サイズ変更オプションはお勧めしません。シンプルに始めて、上に向かって進んでください。使い果たされたときに新しいものを最後に追加するバイトバッファのキューは、良いスタートです。おそらくスレッドの問題に注意を払う必要があるので、私のアドバイスは、他の誰かのスレッドセーフなキューの実装を使用することです。

次に、より複雑な「ポインタ」を大きなバイト配列チャンクに見てみましょう。ただし、インデックスを作成する4k / 16k(ページサイズの2倍の累乗)ブロックのキューを作成することをお勧めします。いっぱいになったら、キューに別の大きなチャンクを追加します。実際、複雑さとパフォーマンスの疑わしい向上のため、これはまったくお勧めしません。

簡単に始めて、上に向かって進んでください。バッファのプール、スレッドセーフにします。さらに何かが必要かどうかを確認します。

于 2009-02-24T14:44:11.163 に答える
2

複数のバッファにもう 1 票を投じますが、非同期で処理を行っているため、キューがスレッドセーフであることを確認する必要があります。デフォルトのQueue<T>コレクションは明らかにスレッドセーフではありません

SO ユーザーと MS の従業員であるJaredParには、スレッドセーフなキューが適切に実装されています

于 2009-02-24T14:50:01.430 に答える
1

ガベージ コレクション ヒープでは、有効期間が短い適切なサイズの小さいバッファーを常に優先する必要があります。.NET ヒープ アロケーターは非常に高速で、ジェネレーション #0 コレクションは非常に安価です。

静的バッファーを維持すると、プログラムの存続期間中、システム リソースを使い果たすことになります。最悪のシナリオは、Large Object Heap に移動するのに十分な大きさになり、移動できない永続的な障害になる場合です。

于 2009-02-24T16:01:22.023 に答える
1

単一のバッファーを使用する場合は、必要なときにどれだけ速く拡張するかについての戦略が必要です。少しずつ拡大する場合は、頻繁に実行し、すべてのデータを頻繁にコピーする必要がある場合があります。大きな増分で大きくすると (次のサイズが前のサイズの 1.5 倍になるように)、バッファを大きくしようとして単に「メモリ不足」になる状況に直面するリスクがあります。これは、スケーラブルなシステムにとっては負け負けの選択です。これが、小さなバッファーの再利用が望ましい理由です。

于 2009-02-24T14:58:06.730 に答える