我正在尝试分析我在较大计算机(32核,256GB RAM)上编写的多线程程序。我注意到,在运行之间,程序的性能可能会发生很大的变化(70-80%)。我似乎找不到程序性能如此巨大差异的原因,但是通过分析大量运行中“time”实用程序的结果,我注意到非自愿上下文切换的数量与程序性能(显然,较少的上下文切换导致更好的性能,反之亦然)。

有什么好的方法来确定是什么导致此上下文切换?如果我能找到罪魁祸首,那么也许我可以尝试解决问题。但是,我对可以使用的工具有一些特别的限制。首先,我在计算机上没有root特权,因此所有需要这种特权的工具都已退出。其次,它是一个相当老的内核(RHEL5,内核2.6.18),因此某些标准的perf-event东西可能不存在。无论如何,任何有关如何更深入地了解这种上下文切换原因的建议都将不胜感激。

更新:我决定在另一台(和更小的)计算机上测试我的程序。另一台计算机是具有8Gb RAM的4核(带有超线程处理功能)Linux机器,而另一台计算机则是更新得多的内核-3.2.0与2.6.18。在新机器上,我无法重现双峰性能曲线。这使我相信,该问题是由于硬件问题(如注释中所建议的),或者是由于此后已解决的内核级别的特殊病理情况。我目前的最佳假设是,这可能是由于新计算机的内核带有完全公平的调度程序(CFS)而旧计算机没有内核。有没有一种方法可以测试这个假设(告诉新机器使用不同的/较旧的调度程序),而不必为新机器重新编译古老的内核版本?

最佳答案

您提到有32个内核,但是硬件的确切布局是什么?例如。机器有多少个软件包,有多少个内核,如何共享缓存等。对于共享此类信息,我个人喜欢共享likwid-topology -g的输出。

无论如何,您的运行中存在一种不确定性:线程亲和力。操作系统分配SW线程以某种方式在特定的HW线程上运行,而无需考虑有关线程如何通信的知识(只是因为它不具备该知识)。这可能会导致各种影响,因此对于可重现的运行,最好确保以某种方式将SW线程固定在HW线程上(也可能是一种最佳方式,但是到目前为止,我只是在讨论确定性)。

要固定(也称为亲和力),您可以使用显式的Pthread调用,也可以尝试使用Likwid套件中的另一个工具likwid-pin-参见here

如果这样做不能带来一致的结果,请对您的工作负载运行良好的探查器(例如Intel VTune),以确保捕获较快的运行和较慢的运行,然后比较结果。在VTune中,您可以使用比较功能,该功能可以并排显示两个配置文件。

关于c++ - 非自愿上下文切换的原因,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17266285/

10-11 16:28