我们希望将我们服务器上的操作系统从 Ubuntu 10.04 LTS 升级到 Ubuntu 12.04 LTS。不幸的是,运行可运行线程的延迟似乎已经从2.6内核显著增加到了3.2内核。事实上,我们得到的延迟数字是难以置信的。
让我说得更具体一点。我们有一个运行两个线程的程序。第一个线程获取当前时间(使用 RDTSC 以刻度表示) ,然后每秒发出一次条件变量信号。第二个线程等待条件变量,并在收到信号时唤醒它。然后获取当前时间(使用 RDTSC 以刻度表示)。第二个线程中的时间与第一个线程中的时间之间的差异将被计算并显示在控制台上。在此之后,第二个线程再次等待条件变量。大约一秒钟后,第一个线程将再次发出信号。
因此,简而言之,我们得到了一个 通过条件变量进行线程到线程的通信延迟测量结果每秒一次。
在内核2.6.32中,这个延迟在2.8-3.5 us 之间,这是合理的。在内核3.2.0中,这种延迟已经增加到40-100 us。我排除了两台主机在硬件上的任何差异。它们运行在相同的硬件上(双套接字 X5687{ Westmere-EP }处理器运行在3.6 GHz,超线程,快步和所有 C 状态关闭)。测试应用程序改变了线程的亲和力,让它们在同一个套接字的独立物理内核上运行(例如,第一个线程在 Core 0上运行,第二个线程在 Core 1上运行) ,所以线程在内核上不会弹跳,套接字之间也不会弹跳/通信。
两个主机之间的唯一区别是,一个运行的是内核2.6.32-28版本的 Ubuntu 10.04 LTS (快速上下文切换框) ,另一个运行的是内核3.2.0-23版本的最新 Ubuntu 12.04 LTS (慢速上下文切换框)。所有的 BIOS 设置和硬件都是相同的。
内核中是否有任何变化可以解释这种荒谬的线程运行时间的减慢?
更新: 如果你想在你的主机和 linux 版本上运行测试,我有 把代码发到 pastebin供你阅读。编制:
g++ -O3 -o test_latency test_latency.cpp -lpthread
使用以下命令运行(假设您至少有一个双核机顶盒) :
./test_latency 0 1 # Thread 1 on Core 0 and Thread 2 on Core 1
更新2 : 在对内核参数、内核更改和个人研究进行了大量搜索之后,我找出了问题所在,并发布了解决方案作为这个问题的答案。