加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用托管内存进行已注册的I / O RIOSend函数调用

发布时间:2020-12-15 05:37:52 所属栏目:百科 来源:网络整理
导读:我正在研究一个需要高速,低延迟/抖动通信的系统,它是用C#编写的.我们看到有一种新机制可以通过名为 Windows Registered IO http://www.serverframework.com/asynchronousevents/2011/10/windows-8-registered-io-networking-extensions.html的套接字获得更好
我正在研究一个需要高速,低延迟/抖动通信的系统,它是用C#编写的.我们看到有一种新机制可以通过名为 Windows Registered IO http://www.serverframework.com/asynchronousevents/2011/10/windows-8-registered-io-networking-extensions.html的套接字获得更好的性能

…但目前还没有C#可用……而且基于C测试肯定会表现出更好的性能.

无论如何,我已经编写了Managed C/C++LI部分来创建一个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 );
}

其中_RIObs是实现已注册I / O功能的非托管C对象.在该函数中,它将数据复制到使用RIORegisterBuffer()在启动时注册的缓冲区,然后调用RIOSend()以通知操作系统有数据要发送.

所以,我的问题是我可以让这个Managed C对象的用户在启动时传入一个托管字节数组,并在其上调用GCHandle :: Alloc()来修复它并防止垃圾回收,在其上调用RIORegisterBuffer()托管应用程序,然后在托管C对象存活时使用它?我将注册该托管缓冲区内存而不是非托管内存,当用户想要发送数据时,它们将填满他们已经引用的缓冲区,并通知我们要发送多少字节.这是一个阻塞发送并等待一个完成事件,所以他们不会再次使用缓冲区,直到操作系统完成它与数据的关系.

只要非托管应用程序可以互换使用托管或非托管内存,只要托管内存被锁定直到不再需要它,它似乎就可以工作.

解决方法

您可以直接从C#调用RIO,而不是通过C/C++LI;分配大缓冲区> 85k将它移动到LoH而不是干扰常规GC,然后你可以使用类似于你的建议:
_underlyingBuffer = new byte[BufferLength];
var pinnedBuffer = GCHandle.Alloc(_underlyingBuffer,GCHandleType.Pinned);
var address = Marshal.UnsafeAddrOfPinnedArrayElement(_underlyingBuffer,0);
var bufferId = _rio.RegisterBuffer(address,BufferLength);

我已经使用direct interop to Registered IO和some analysis的示例来组建一个示例http echo服务器(非常好).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读