Iperf: 多线程 iperf3

创建于 2015-08-04  ·  21评论  ·  资料来源: esnet/iperf

你好,

我一直在运行 Fedora 21 的具有 4 个内核(8 个线程)的机器上使用 Iperf3(来自 GitHub 的最新代码)。
我注意到即使在使用多个流(-P 选项)进行测试时,也只使用了两个线程。 与 Iperf2 相同的最基本的多流测试利用了所有内核。
我错过了什么吗? 任何想法为什么它可能会这样?

问候,
列昂尼德。

question

所有21条评论

按照设计,iperf3 不是多线程的。 您是否有任何迹象表明您的测试受 CPU 限制?

即使设置了 -P 选项,iperf3 也不是多线程的吗?

这大概说明了。
+1 wangyoucao577的问题。
我很好奇:为什么会这样? 因为 Iperf2 是多线程的。

@ wangyoucao577,@blochl:iperf3是一个完全重写和股票代码非常少,在共同与iperf3。 预期用例是测试高速单流性能,这是 R&E 网络科学工作流的典型特征。 这不需要并行线程的多线程。

@blochl :你还没有回答我关于 iperf3 的单线程设计是否真的给你带来了问题的问题。

在我们的测试场景中,还测量了 CPU 负载。 使用 Iperf3,与 Iperf2 不同,CPU 负载始终为 ~100%,但在单个 CPU 上,它没有给出 CPU 负载作为函数(例如缓冲区大小)的太多指示。 这就是问题。

好的。 我明白你所看到的。 我相信多线程 iperf3 将是一项非常重要的工作(设计早于我参与这个项目),尽管我承认我并没有真正考虑太多。

我也试过这种情况。 如果使用 iperf 并设置 '-P' 选项,我可以找到多个线程。 但是如果使用iperf3并设置'-P'选项,客户端只有一个线程。 所以'-P'的行为在iperf和iperf3之间也不同。 请问iperf3为什么要放弃多线程工具? 在这里使用多线程或仅使用多套接字有什么区别吗?

伙计们,iperf3 的单线程行为并不神秘,不需要任何人进行任何调查。 它不是为多线程而设计的,并且实现反映了这一点。 我不确定为什么它是这样设计的。 也许与最初的 iperf3 工作更密切相关的人可以对此有所了解(当我休假回来时,我会更积极地询问周围)。

好的。 谢谢。 我只想知道在某些情况下是否需要多线程。 或者也许这并不重要。

@wangyoucao577 :好吧,如果您想在生成流量时测量 CPU 性能,这一点很重要。 也许还有其他情况。
我想知道:如果这个单线程饱和(~100%)是否意味着这可能是一个瓶颈?

但是如果单线程会遇到(~100%)瓶颈,我想多线程也会遇到,不是吗?

@wangyoucao577 :嗯,没有。 为什么会这样? 如果某个负载导致单个线程使用 100%,则可以将其分散到多个线程,每个线程都会占用更少,恕我直言。
此外,在实验上,在相同的参数下,Iperf2 在每个线程上占用 20-60%,并且使用所有线程,而 Iperf3 在单个线程上占用接近 100%。

为什么? 我无法理解。 多线程不是意味着从一个线程到另一个线程的 CPU 成本更高吗? 为什么结果是单线程占用更多的cpu? 在我的理解中,比如 iperf2 在每个线程上占用 20-60%,但这些线程的总和将超过 100%,不是吗?

@布洛赫
或者你的意思是说对于多cpu核心的pc,多线程可以使用多cpu核心来承受测试,而单线程只能使用1个cpu核心,所以可能不足以进行高网络性能测试?

@wangyoucao577 :我的意思是使用~100% 的单核。 多线程本可以使用更少的时间,但在多核上。 瓶颈问题暂时只是猜测,但对于并行测试CPU和网络性能来说,这无疑是重要的。

CPU 使用率似乎是一个瓶颈,是的。

root<strong i="6">@foobar</strong>:~# iperf3 -c ::1 -i1 -t10 -w32M -P8
[SUM]   0.00-10.00  sec  30.9 GBytes  26.5 Gbits/sec                  receiver

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
14278 root       20   0  8948  3892  1208 R 101.  0.1  0:05.44 iperf3 -s
14279 root       20   0  8948  3868  1184 R 81.6  0.1  0:04.67 iperf3 -c ::1 -i1 -t10 -w32M -P8

如果我同时启动另一组 iperf3(不同的端口),我们会清楚地看到 CPU 造成了瓶颈(而不是网络堆栈,因为两个并行运行的带宽增加了一倍);

root<strong i="10">@foobar</strong>:~# iperf3 -c ::1 -i1 -t10 -w32M -P8 -p5202
[SUM]   0.00-10.00  sec  31.3 GBytes  26.9 Gbits/sec                  receiver

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
14270 root       20   0  7412  2368  1216 R 101.  0.1  0:16.32 iperf3 -s -p 5202
14283 root       20   0  7412  2392  1220 R 101.  0.1  0:49.77 iperf3 -s
14287 root       20   0  7412  2396  1252 R 81.3  0.1  0:09.96 iperf3 -c ::1 -i1 -t10 -w32M -P8 -p5202
14286 root       20   0  7412  2308  1160 R 78.9  0.1  0:15.12 iperf3 -c ::1 -i1 -t10 -w32M -P8

另一个问题是 iperf2 用于为每个线程启动连接,这意味着不同的临时端口。 这会导致在任何网络功能中使用的散列算法看到许多连接而不是少数连接,并且可以帮助/损害您的实现的性能。 看起来我可以达到 8 - 但现在不能更多。

我绝对同意跨越多个内核的选项——在 iperf2 中存在——在浸泡测试中很有用。 然而,应该注意的是,iperf2 仅通过使用多个客户端 - 服务器连接来实现这一点,每个套接字都有一个线程。

然而,在 iperf2 的实现中有一些绝对丑陋的逻辑。 基本上,它在其 C++ 实现中包装了 UDP 套接字,以按照 TCP accept() 如何为入站流创建新套接字的方式工作。

它可以做得更好,但它确实让我觉得它是 iperf3 当前版本中的一项重要工作。

iperf2 使用的多个流的性能问题可能与缺乏自下而上的亲和力有关,甚至可能与缓存线效应有关。 iperf2 不知道 RSS 或其他机制,据我所知,唯一真正可移植的固定套接字工作负载的方法是使用 hwloc 之类的东西了解核心/线程拓扑,然后使用适当的 setockopt()/平台 CPU固定 API。

TCP/IP 堆栈本身中的 PCB 散列 [es] 通常非常高效。 除非您循环使用新连接,否则哈希管理本身可能不是一个问题。

我一直在抱怨 iperf2 中的 UDP,但它的方法的一个优点是每个线程(测量会话中的每个子流)使用的套接字可以显式地绑定()和“listen()”(包装)在每个短暂的端口,而不是直接使用 recvfrom()。 这可能具有适度的缓存优势。

单线程设计也是嵌入式系统(如路由器)上的一个大问题。 我有一个基于双核 MIPS 的路由器,它可以执行 4 个线程(DIR-860L),我看到 iperf3 正在最大限度地使用单核,但没有达到千兆速度。 绝对受单线程设计的限制。

建议您改用 iperf2。

iperf(2) 为每个流创建线程,然而,iperf3 只有一个线程发送多个流。
所以,你可以看到 theads 使用 htop w/ iperf -P x,但只有 1 个 thead w/ iperf3 -P x。
iperf 和 iperf3 都有多个发送端口。

此页面是否有帮助?
0 / 5 - 0 等级