我正在对一个大型科学应用程序进行基准测试,发现在相同的输入下它有时会慢 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 上运行,但如果设置了处理器亲和性,它就会不受干扰。
底线:如果您需要在多核机器上对单线程程序进行准确的基准测试,请确保设置处理器亲和性。