我正在对一个大型科学应用程序进行基准测试,发现在相同输入的情况下它有时会慢10%。经过大量搜索,我发现只有在我的四核CPU核心#2(特别是运行在2.4 GHz的Intel Q6600)上运行时才会出现减速。该应用程序是单线程的,并且大部分时间都花在CPU密集型矩阵数学例程中。
现在我知道一个核心比其他核心慢,我可以通过将处理器亲和力设置为所有运行的相同核心来获得准确的基准测试结果。但是,我仍然想知道为什么一个核心速度较慢。
我尝试了几个简单的测试用例来确定CPU的慢速部分,但测试用例运行时间相同,即使在慢速核心#2上也是如此。只有复杂的应用程序显示减速。以下是我尝试的测试用例:
浮点乘法和加法:
accumulator = accumulator*1.000001 + 0.0001;
三角函数:
accumulator = sin(accumulator);
accumulator = cos(accumulator);
整数加法:
accumulator = accumulator + 1;
尝试使L2缓存未命中时的内存复制:
int stride = 4*1024*1024 + 37; // L2 cache size + small prime number
for(long iter=0; iter<iterations; ++iter) {
for(int offset=0; offset<stride; ++offset) {
for(i=offset; i<array_size; i += stride) {
array1[i] = array2[i];
}
}
}
问题:为什么一个CPU内核比其他内核慢,哪个CPU部分导致这种减速?
编辑:更多测试显示了一些Heisenbug行为。当我明确设置处理器亲和性时,我的应用程序不会减慢核心#2的速度。但是,如果它选择在没有明确设置处理器关联的情况下在核心#2上运行,那么应用程序运行速度会慢大约10%。这就解释了为什么我的简单测试用例没有显示相同的减速,因为它们都明确设置了处理器亲和性。所以,看起来有一些流程喜欢在核心#2上生存,但如果设置了处理器亲和性,它就会失控。
底线:如果您需要在多核计算机上获得单线程程序的准确基准,请确保设置处理器关联。
答案 0 :(得分:7)
您可能有选择连接到同一处理器的应用程序(CPU Affinity)。
操作系统通常喜欢在同一个处理器上运行,因为它们可以将所有数据缓存在同一个L1缓存上。如果您碰巧在您的操作系统执行大量工作的同一核心上运行您的进程,您可能会遇到CPU性能下降的影响。
听起来有些进程想要坚持使用相同的cpu。我怀疑这是硬件问题。
它不一定是你的操作系统正在做的工作,其他一些后台守护进程可能会这样做。
答案 1 :(得分:2)
由于过热或省电功能,大多数现代cpu都对每个cpu核心进行单独限制。您可以尝试关闭节电或改善散热。或者也许你的CPU很糟糕。在我的i7上,我获得了“传感器”中8个报告核心的2-3度不同的核心温度。满负荷时仍有变化。
答案 2 :(得分:1)
另一种可能性是该进程在运行时从一个核心迁移到另一个核心。我建议将CPU亲和力设置为'慢'核心,看看它是否同样快。
多年前,在多核时代之前,我为自己买了一个用于'web开发'的双插槽Athlon MP。突然间,我的Plone / Zope / Python Web服务器慢慢爬行。谷歌搜索发现CPython解释器具有全局解释器锁,但Python线程由OS线程支持。操作系统线程均匀分布在CPU之间,但只有一个CPU可以一次获取锁,因此所有其他的processes had to wait。
将Zope的CPU亲和力设置为任何CPU都可以解决问题。
答案 3 :(得分:0)
我在Haswel笔记本电脑上观察到了类似的东西。系统很安静,没有X运行,只有终端。使用不同的numactl --physcpubin
选项执行相同的代码在所有核心上给出了完全相同的结果,除了一个。我将内核的频率更改为Turbo,其他值没有任何帮助。所有核心都以预期的速度运行,除了一个总是比其他核心运行速度慢的核心。这种效果在重新启动后幸存下来。
我重新启动了计算机并在BIOS中关闭了HyperThreading。当它重新上线时再次没问题了。然后我开启了HyperThreading,直到现在都很好。
的bizzare。不知道那可能是什么。