我有一个 Java 应用程序,通过 TCP 套接字连接到用 C/C++ 开发的“服务器”。
应用程序和服务器都在同一台机器上运行,一台 Solaris 机器(但我们正在考虑最终迁移到 Linux)。 交换的数据类型是简单的消息(登录、登录 ACK、然后客户端请求某些内容、服务器回复)。每条消息大约 300 字节长。
目前我们正在使用套接字,一切正常,但是我正在寻找一种更快的方式来交换数据(更低的延迟),使用 IPC 方法。
我一直在研究网络,并引用了以下技术:
- 共享内存
- 管道
- 队列
- 以及所谓的 DMA(直接内存访问)
但我找不到对它们各自性能的正确分析,也找不到如何在 JAVA 和 C/C++ 中实现它们(以便它们可以相互交谈),除了我可以想象如何做的管道。
在这种情况下,任何人都可以评论每种方法的性能和可行性吗? 任何指向有用实现信息的指针/链接?
编辑/更新
根据我在这里得到的评论和答案,我找到了有关 Unix 域套接字的信息,它似乎是在管道上构建的,并且可以为我节省整个 TCP 堆栈。 它是特定于平台的,因此我计划使用 JNI 或 juds 对其进行测试或 junixsocket .
下一个可能的步骤是直接实现管道,然后是共享内存,尽管我已经被警告过额外的复杂性......
感谢您的帮助
最佳答案
刚刚在我的 Corei5 2.8GHz 上测试了 Java 的延迟,只有单字节发送/接收, 2 个 Java 进程刚刚产生,没有为任务集分配特定的 CPU 内核:
TCP - 25 microseconds
Named pipes - 15 microseconds
现在明确指定核心掩码,例如 taskset 1 java Srv 或 taskset 2 java Cli:
TCP, same cores: 30 microseconds
TCP, explicit different cores: 22 microseconds
Named pipes, same core: 4-5 microseconds !!!!
Named pipes, taskset different cores: 7-8 microseconds !!!!
所以
TCP overhead is visible
scheduling overhead (or core caches?) is also the culprit
同时 Thread.sleep(0)(如 strace 所示导致执行单个 sched_yield() Linux 内核调用)需要 0.3 微秒 - 因此调度到单核的命名管道仍然有很多开销
一些共享内存测量: 2009 年 9 月 14 日 - Solace Systems 今天宣布,其统一消息平台 API 可以使用共享内存传输实现低于 700 纳秒的平均延迟。 http://solacesystems.com/news/fastest-ipc-messaging/
附: - 第二天以内存映射文件的形式尝试共享内存, 如果可以接受忙等待,我们可以将延迟减少到 0.3 微秒 用这样的代码传递一个字节:
MappedByteBuffer mem =
new RandomAccessFile("/tmp/mapped.txt", "rw").getChannel()
.map(FileChannel.MapMode.READ_WRITE, 0, 1);
while(true){
while(mem.get(0)!=5) Thread.sleep(0); // waiting for client request
mem.put(0, (byte)10); // sending the reply
}
注意:需要 Thread.sleep(0) 以便 2 个进程可以看到彼此的更改 (我还不知道另一种方式)。如果 2 个进程被迫与任务集同核, 延迟变为 1.5 微秒 - 这是上下文切换延迟
P.P.S - 0.3 微秒是个好数字!以下代码只需要 0.1 微秒,而只进行原始字符串连接:
int j=123456789;
String ret = "my-record-key-" + j + "-in-db";
P.P.P.S - 希望这不是太离题,但最后我尝试用增加一个静态 volatile int 变量(JVM 碰巧在这样做时刷新 CPU 缓存)替换 Thread.sleep(0) 并获得 - 记录! - 72 纳秒延迟 java 到 java 进程通信!
然而,当强制使用相同的 CPU 内核时,增加 volatile 的 JVM 永远不会相互控制,因此会产生 10 毫秒的延迟 - Linux 时间量似乎是 5 毫秒...所以只有在存在备用核心 - 否则 sleep(0) 更安全。
关于java - Java 和 C/C++ 之间进程间通信的最快(低延迟)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2635272/