java - Java 和 C/C++ 之间进程间通信的最快(低延迟)方法

标签 java c++ performance ipc latency

我有一个 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 Srvtaskset 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/

相关文章:

java - 如何根据用户输入创建 JLabel 和 JRadioButton?

c++ - 私有(private)类的 friend

android - 协程限制?

java - 使用 ArrayList 的优先级队列的性能

php - Ubuntu 10.4 上的 APC 配置。 apc.shm_size、apc.shm_segments 和 Apache 的问题

java - Apache Storm 应用程序运行失败

java - IntelliJ 找不到 "GL10"LibGDX 程序的 "Hello World"库

java 。如何通过远程 channel 连接到远程Websphere MQ?

c++ - 从声明为 std::set<std::shared_ptr<Edge>> edges_ 的 edges_ 中删除边;

c++ - 如何确保在不满足条件时不运行特定代码