1

有谁知道是否可以从套接字直接读取到内存映射的 .NET 文件中的某个位置?如果有帮助,这恰好是一个非持久内存映射文件(纯粹在内存中,没有关联的磁盘文件)。

上下文:我正在尝试在分布式系统中有大型内存映射对象从一个节点移动到另一个节点的情况下实现最小复制代码。我通过标准套接字库使用 UDP,所以我希望能够从套接字读取 64KB(我在 Infiniband 网络上,所以 MTU 可能非常大)到某个位置的偏移量进入内存映射区域。

到目前为止,我发现的所有内容似乎都涉及执行复制操作——首先读取我的数据,然后将其复制到内存映射文件中。所以这就是我想避免的:复制操作。事实上,我有同样的发送问题:我想直接从内存映射文件发送。

虽然复制可能看起来很小,但我正在使用的对象是巨大的(云场景):大量数千兆字节的内存映射对象,我想将其视为字节数组。所以那些额外的复制操作对我来说可能很昂贵。事实上,我真正的目标是使用 Infiniband 动词,并从机器 A 上的内存映射区域直接 DMA 传输到机器 B 上的内存映射区域,完全绕过 UDP。

任何指针将不胜感激!

(更多细节:这些是大型集群、64 位机器上的应用程序,虽然我的代码是用 C# 编写的 .NET,但创建这些内存映射对象的应用程序大多是用 C++ 或其他语言编写的——将它们视为 Hadoop或 Mapreduce 任务,例如,文件作为巨大的图像,或连接的网页,诸如此类。所以这些应用程序产生这些文件——可能是 Map 步骤的输出——现在它们需要“洗牌”到正确的地方。这是我正在尝试做的具体事情......理想情况下,我的代码仍然存在于 .NET/C# 中,仅仅是因为我喜欢 .NET 中的 C#。我使用 Mono for Linux 进行交叉编译......实际上是他们在这些集群上运行的)

4

1 回答 1

0

显然,Keith 为我指出了正确的方向值得称赞,但总结一下答案:最适合我的是用 C 或 C++ 编写一个小模块,编译它以创建一个 DLL,该 DLL 将成为我的程序集的一部分,并且加载它(这可以动态或静态完成;当然后者更容易)。然后我可以从 C# 调用到 C 中,我的 C 代码可以使用真实地址进行原始系统调用。由于内存映射文件(即使是没有持久存储的文件)由于垃圾收集或合并而不会移动,所以这是一个异常简单的情况。事实上,C 代码甚至不需要从 C# 代码中学习地址——它可以“重新映射”同一个文件,尽管传递地址应该很容易。此外,当您开始使用它时,它可以像我的原始 C# 代码一样具有可移植性。

相比之下,在没有一两个辅助程序的情况下这样做会很痛苦。

基思,如果您想以您的名义重新发布此内容,我将删除我的摘要并“投票”您到顶部(您应该得到积分......)

于 2013-07-18T22:52:45.967 回答