如何消除由于CPU核心数量增加而导致的开销

时间:2015-06-03 07:13:26

标签: performance networking linux-kernel multicore

我们遇到这样的情况,即8核心的服务器在6分钟内初始化服务,而另一台具有32个CPU核心的服务器需要35分钟来初始化服务。在正确分析之后,我们已经看到它是由于两个内核API(get_counters和snmp_fold_field)尝试从每个现有内核收集数据,并且随着cpu内核数量的增加,执行时间比预期的要长。为了减少初始化我们考虑禁用额外内核以及稍后初始化启用所有cpu内核的时间。但是在这种方法中,一旦我们启用所有内核同步发生在新启用的内核上,因为这是SMP内核。

有人可以建议我们如何有效地减少因增加CPU内核而导致的开销吗?

相反代码我宁愿解释这个用户定义的系统服务的初始化功能。在初始化时,该服务在配置的IP上检测虚拟接口。为了避免每个配置的IP重叠IP情况,它会创建一个内部IP,所有通信都在内部IP上检测到的接口上完成。当数据包到达目的地为配置IP的系统时,将应用Mangling / NATting / Routing表规则。系统来管理它。 一个接口也可以用于配置Ip以避免IP转发。我们的问题是当我们在8核计算机上扩展配置为1024个IP的系统时需要8分钟,在32个核心上需要35分钟。

使用系统分析进行进一步的调试我们看到ARPtables / IPtables的内核模块在" get_counters()"和IP的内核模块在snmp_fold_field()中消耗时间。如果我只是禁用ARPtables Mangling规则从35分钟开始下降到18分钟。我可以共享使用profiler收集的内核模块的callstack。

1 个答案:

答案 0 :(得分:0)

利用多核的应用程序中的常见瓶颈是对共享资源的不受控制/优化的访问。最大的性能杀手是总线锁(关键部分),然后访问RAM,访问L3缓存和访问L2缓存。只要核心在其自己的L1(代码和数据)缓存中运行,唯一的瓶颈就是由于编写得不好的代码和组织严密的数据。当两个核心需要超出其L1缓存时,它们可能在访问其(共享)L2缓存时发生冲突。谁先走了?数据是否存在或者我们必须向下移动到L3或RAM才能访问它?对于查找数据所需的每个更高级别,您需要花费3-4倍的时间惩罚。

关于您的应用程序,它似乎运行得相当好,因为八个核心在访问共享资源时只能在一定程度上发生冲突。有三十二个核心,问题变成了四倍以上,因为你将拥有四倍的资源压力和四倍的核心来解决谁先获得访问权限。它就像一个门口:只要有几个人现在进出门口,就没有问题了。接近门口的人可能会停下来让另一个人通过。突然之间你会遇到许多人进出的情况,你不仅会出现拥堵,还会遇到交通拥堵。

我的建议是尝试限制应用程序在任何时候都可以使用的线程数(这将转换为核心数)。八个核心上的六分钟启动时间可以作为基准。您可能会发现它将在四个内核上执行得比八个更快,更不用说三十二个了。

如果是这种情况,你仍然坚持要比现在更快地在32个内核上运行,那么你正在寻找大量的工作,既可以提高SNMP服务器代码的效率,也可以组织数据来减少加载共享资源。不适合胆小的人。您最终可能会重写整个应用程序。