我们正在编写一个前端,它应该处理大量的流量(在我们的例子中是Diameter流量,但这可能与问题无关)。当客户端连接时,服务器套接字被分配给执行所有实际流量处理的工作进程之一。换句话说,Worker完成了所有的工作,当更多的客户端连接时,应该添加更多的Worker。
对于不同数量的Worker,每个消息的CPU负载应该是相同的,因为Worker是完全独立的,并为不同的客户端连接提供服务。然而,我们的测试表明,随着Worker数量的增加,每条消息需要更多的CPU时间。
更准确地说,CPU负载取决于TPS (每秒的事务或请求-响应),如下所示。
对于1个工人: 60K TPS - 16%,65K TPS - 17%...即每KTPS约0.26%的CPU
对于2个工人: 80K TPS - 29%,85K TPS - 30%...即每KTPS约0.35%的CPU
对于4名工人: 85K TPS - 33%,90K TPS - 37%...即每KTPS约0.41%的CPU
对此有何解释?工作进程是独立的进程,它们之间不存在进程间通信。而且,每个Worker都是单线程的。
编程语言是C++在任何硬件上都可以观察到这种影响,这与下面的硬件很接近:2个Intel Xeon CPU,4-6核,2-3个GHz操作系统: RedHat Linux (RHEL) 5.8,6.4CPU负载测量是使用mpstat和top完成的。
发布于 2015-01-16 22:58:15
如果worker使用的程序代码的大小或worker (或两者)处理的数据的大小都不小,则的原因可能是各种缓存的有效性降低:单个worker如何访问其程序代码和/或其数据被其他worker干扰的时间局部性。
这种效果可能很难理解,因为:
注意:考虑到进程调度的粒度相对较粗,我认为这一点的影响不应该像它那样大。
但话说回来:您是否查看过“CPU百分比”是如何定义的?在你的机器上达到CPU 饱和度之前,你不能确定效果是否真的像它看起来那样大。当您达到饱和时,这里的瓶颈可能根本不是CPU,所以您确定需要关心CPU负载吗?
发布于 2015-01-17 00:27:14
我完全同意@Lutz Prechelt。在这里,我只想添加关于如何调查问题的方法,答案是Perf。
Perf是Linux中的一个性能分析工具,它同时收集内核和用户空间事件,并提供一些很好的指标。它在我的团队中被广泛使用,用来找出CPU应用程序的瓶颈。
perf的输出如下所示:
Performance counter stats for './cache_line_test 0 1 2 3':
1288.050638 task-clock # 3.930 CPUs utilized
185 context-switches # 0.144 K/sec
8 cpu-migrations # 0.006 K/sec
395 page-faults # 0.307 K/sec
3,182,411,312 cycles # 2.471 GHz [39.95%]
2,720,300,251 stalled-cycles-frontend # 85.48% frontend cycles idle [40.28%]
764,587,902 stalled-cycles-backend # 24.03% backend cycles idle [40.43%]
1,040,828,706 instructions # 0.33 insns per cycle
# 2.61 stalled cycles per insn [51.33%]
130,948,681 branches # 101.664 M/sec [51.48%]
20,721 branch-misses # 0.02% of all branches [50.65%]
652,263,290 L1-dcache-loads # 506.396 M/sec [51.24%]
10,055,747 L1-dcache-load-misses # 1.54% of all L1-dcache hits [51.24%]
4,846,815 LLC-loads # 3.763 M/sec [40.18%]
301 LLC-load-misses # 0.01% of all LL-cache hits [39.58%]它输出你的缓存未命中率将使你轻松地调整你的程序,并看到效果。
我写了一篇关于cache line effects and perf的文章,你可以阅读它来了解更多细节。
https://stackoverflow.com/questions/27986273
复制相似问题