5

私は、高速で低遅延/ジッター通信を必要とするシステムに取り組んでおり、C# で記述されています。Windows Registered IO http://www.serverframework.com/asynchronousevents/2011/10/windows-8-registered-io-networking-extensions.htmlと呼ばれるソケットでパフォーマンスを向上させる新しいメカニズムがあることを確認しました。

...しかし、現時点では C# では利用できません ...そして、C++ でのテストに基づいて、明らかに優れたパフォーマンスを示しているようです。

とにかく、マネージ C++/CLI 部分を既に作成して DLL を作成しました。これは、C# と大幅に改善された数値で問題なく動作するようです。

しかし、送信でバッファコピーを保存できるかどうか疑問に思っています...

現在、C++ ラッパーは次のようになっています。

bool ManagedSendData( array<byte> ^ buf, ULONG bufLen )
{
// must pin array memory until we're done with sending it, 
// at which point it'll be copied into the unmanaged memory

   pin_ptr<Byte> p = &buf[0];   // pinning one element of an array pins the whole array
   unsigned char * cp = p;

   return _RIObs->SendData( cp, bufLen );
}

_RIObsRegistered I/O 機能を実装するアンマネージ C++ オブジェクトはどこにありますか。その関数では、起動時に で登録したバッファにデータをコピーし、RIORegisterBuffer()を呼び出しRIOSend()て、送信するデータがあることを OS に通知します。

したがって、私の質問は、このマネージ C++ オブジェクトのユーザーに、起動時にマネージ バイト配列を渡してもらいGCHandle::Alloc()、それを呼び出してその場で修正し、ガベージ コレクションを防止RIORegisterBuffer()し、マネージ アプリケーションで呼び出してから使用できるようにすることはできますか?マネージ C++ オブジェクトは生きていますか? アンマネージ メモリの代わりにそのマネージ バッファ メモリを登録します。ユーザーがデータを送信したい場合は、既に参照しているバッファをいっぱいにして、送信したいバイト数を通知するだけです。これはブロッキング送信であり、完了イベントを待機するため、OS がデータを処理するまでバッファを再び使用することはありません。

マネージド メモリが不要になるまでロックダウンされている限り、アンマネージド アプリケーションがマネージド メモリとアンマネージド メモリを交換可能に使用できる限り、機能するようです。

4

2 に答える 2

3

C++/CLI 経由ではなく、C# から直接 RIO を呼び出すことができます。通常のGCに干渉するのではなく、LoHに移動する85kを超える大きなバッファを割り当ててから、提案しているものと同様に使用できます。

_underlyingBuffer = new byte[BufferLength];
var pinnedBuffer = GCHandle.Alloc(_underlyingBuffer, GCHandleType.Pinned);
var address = Marshal.UnsafeAddrOfPinnedArrayElement(_underlyingBuffer, 0);
var bufferId = _rio.RegisterBuffer(address, BufferLength);

Registered IOへの直接相互運用を使用してサンプルの http エコー サーバーを作成し、そのパフォーマンスを分析しました (非常に良好)。

于 2015-07-26T09:52:21.067 に答える
1

それは素晴らしい戦略のように聞こえます。メモリが移動されないように、GCHandle を作成するときに必ず GCHandle::Pinned を使用してください。

于 2013-10-30T05:13:22.247 に答える