如何实现仅使用用户态内存进行传输的 NIO 通道?
How can I implement an NIO Channel using only userland memory for transport?
上下文:
我有一个相当频繁地使用 NIO 的应用程序。它有一个可插入的传输机制,我正在研究各种底层传输如何根据传输执行基准测试。 IO 性能很重要,并且该应用程序只能与同一台计算机上的其他进程进行通信,因此我正在使用 TCP 套接字、UDP 套接字、FileChannel
s 和围绕几个 UNIX_AF 的非阻塞包装器进行测试套接字库。
为了获得这些基准测试,并在此系统上执行测试,拥有一个使用标准 NIO 函数遍历整个 server/handling 堆栈的 "fastest possible" 控制组实现将非常有用, 但以 thread/memory 访问速度运行。
问题:
如何实现 Channel
可以与 NIO 生态系统的其余部分一起使用,但只执行内存中用户空间操作的实现?基本上,我想替换通过 epoll
/select
/kevent
/etc 访问的底层传输系统。具有线程安全的数据结构访问。
我尝试过的:
我已经使用 Pipe
s(通过默认创建的 Pipe.SinkChannel
和 Pipe.SourceChannel
对象)设置了一个解决方案,可用于测试。
然而,Java 告诉我管道由 KQueue 通道支持,strace
似乎证实了这一点。文档表明 Pipes 将根据使用它们的环境选择它们的后端。因此,Pipes 对基准测试用处不大,因为 Pipe
实现的性能会根据 OS 我的基准测试而改变。
我知道管道可能 faster/more 比通过队列结构在线程之间传递数据 "old-school" 更高效,但第二种方法在跨主机环境的性能方面可能更加一致。
我会实现 ByteChannel,使用内部分配的字节数组作为缓冲区自己编写代码,同步访问以确保刷新到主内存。这将强制进行内存复制,从而避免 nio 的字节缓冲区 class 中可能的效率并使时序更可重复。
上下文:
我有一个相当频繁地使用 NIO 的应用程序。它有一个可插入的传输机制,我正在研究各种底层传输如何根据传输执行基准测试。 IO 性能很重要,并且该应用程序只能与同一台计算机上的其他进程进行通信,因此我正在使用 TCP 套接字、UDP 套接字、FileChannel
s 和围绕几个 UNIX_AF 的非阻塞包装器进行测试套接字库。
为了获得这些基准测试,并在此系统上执行测试,拥有一个使用标准 NIO 函数遍历整个 server/handling 堆栈的 "fastest possible" 控制组实现将非常有用, 但以 thread/memory 访问速度运行。
问题:
如何实现 Channel
可以与 NIO 生态系统的其余部分一起使用,但只执行内存中用户空间操作的实现?基本上,我想替换通过 epoll
/select
/kevent
/etc 访问的底层传输系统。具有线程安全的数据结构访问。
我尝试过的:
我已经使用 Pipe
s(通过默认创建的 Pipe.SinkChannel
和 Pipe.SourceChannel
对象)设置了一个解决方案,可用于测试。
然而,Java 告诉我管道由 KQueue 通道支持,strace
似乎证实了这一点。文档表明 Pipes 将根据使用它们的环境选择它们的后端。因此,Pipes 对基准测试用处不大,因为 Pipe
实现的性能会根据 OS 我的基准测试而改变。
我知道管道可能 faster/more 比通过队列结构在线程之间传递数据 "old-school" 更高效,但第二种方法在跨主机环境的性能方面可能更加一致。
我会实现 ByteChannel,使用内部分配的字节数组作为缓冲区自己编写代码,同步访问以确保刷新到主内存。这将强制进行内存复制,从而避免 nio 的字节缓冲区 class 中可能的效率并使时序更可重复。