java - 多线程降低了 NUMA 上的套接字吞吐量

标签 java linux multithreading sockets numa

我在装有 Red Had Linux 的 16 核 NUMA 机器上对 Java 程序进行了基准测试。我根据每秒能够接收和发送多少数据包(64 字节大小)来测量 Java DatagramSocket(对于 UDP)的吞吐量。该程序由一个套接字和 n 个监听套接字的线程组成。当一个数据包到达时,他们会将有效负载复制到一个 byte[] 数组中,使用该数组创建一个新的 DatagramPacket 并将其直接发送回它的来源。将其视为 UDP 层上的 ping。

  1. 我发现 Java DatagramSocket 套接字在使用多个线程(即两个或四个)时实现的吞吐量要小得多。如果我只使用一个线程来监听套接字,我可以达到每秒 122,000 个数据包的吞吐量,而多个线程只能达到每秒 65,000 个数据包的吞吐量。现在,我了解到线程可能会在 NUMA 机器的任何核心上执行,并且如果内存必须从一个节点传输到另一个节点,内存访问就会变得昂贵。然而,如果我有两个线程,只有一个应该在“错误”的核心上执行,而另一个应该仍然达到非常高的吞吐量。另一种可能的解释是 Datagramsocket 中的同步问题,但这些只是猜测。有人对真正的解释是什么有很好的了解吗?

  2. 我发现在多个端口上多次(并行)执行此程序可以获得更高的整体吞吐量。我用一个线程启动程序四次,每个程序都在单独的端口(5683、5684、5685 和 5686)上使用一个套接字。四个程序的总吞吐量为每秒 370,000 个数据包。总而言之,在同一个端口上使用多个线程会降低吞吐量,而在多个端口上使用一个线程会增加吞吐量。这怎么解释?

系统规范:

硬件:2 个 AMD Opteron(TM) Processor 6212 处理器上有 16 个内核,分为 4 个节点,每个节点 32 GB RAM。频率:1.4 Ghz,2048 KB 缓存。

node distances:
node   0   1   2   3
  0:  10  16  16  16
  1:  16  10  16  16
  2:  16  16  10  16
  3:  16  16  16  10

操作系统是 Red Hat Enterprise Linux 工作站版本 6.4 (Santiago),内核版本 2.6.32-358.14.1.el6.x86_64。 Java 版本 “1.7.0_09”,Java(TM) SE 运行时环境(build 1.7.0_09-b05),Java HotSpot(TM) 64 位服务器 VM(build 23.5-b02, mixed mode) 我使用了 -XX:+UseNUMA 标志。服务器和客户端通过 10GB 以太网连接。

最佳答案

一般来说,只使用一个线程时效率最高。使东西平行将不可避免地引入成本。只有当您可以并行执行的额外工作量超过此成本时,吞吐量才会增加。

现在,Amdahl's law说明了吞吐量的理论增益与您的工作中有多少可以并行化/不能并行化有关。例如,如果只有 50% 的任务是可并行化的,那么无论在该问题上投入多少线程,吞吐量都只能增加 2 倍。请注意,您在链接中看到的图表忽略了添加线程的成本。实际上, native 操作系统线程确实增加了相当多的成本,尤其是。当他们中的很多人试图访问共享资源时。

在您的情况下,当您只使用一个套接字时,您的大部分工作都无法并行化。因此,使用单个线程可提供卓越的性能,而添加线程会使性能变得更糟,因为它们会增加成本。在您的第二个实验中,您通过使用多个套接字增加了可以并行化的工作。因此,尽管使用线程增加了一些成本,但您仍获得了吞吐量。

关于java - 多线程降低了 NUMA 上的套接字吞吐量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18975418/

相关文章:

java - Thread.yield 和 Java 中的非阻塞 IO 一样吗

java - 如何增加 if 语句中的变量以便在另一个语句中使用?

java - 重命名所有类中的 class 类型的局部变量

linux - 如何使用 bash 脚本在日期/时间和另一个日期/时间之间提取日志

linux - 将文件行排列成表格形式

java - future 任务不起作用

java - Java Thread.sleep() 是否释放处理器?

java - 如何使用 Mockito 模拟 System.getProperty

java - Akka:Java 中的 Flow 相当于什么

linux - crontab 无法运行以指定时间间隔获取 url 的 shell 脚本