Я тестировал большое научное приложение и обнаружил, что оно иногда будет работать на 10% медленнее при тех же затратах. После долгих поисков я обнаружил, что замедление произошло только тогда, когда оно работало на ядре № 2 моего четырехъядерного процессора (в частности, на Intel Q6600, работающем на частоте 2,4 ГГц). Приложение является однопоточным и проводит большую часть времени в математических процедурах с интенсивным использованием ЦП.
Теперь, когда я знаю, что одно ядро медленнее других, я могу получить точные результаты тестов, установив привязку процессора к одному и тому же ядру для всех запусков. Однако я все еще хочу знать, почему одно ядро работает медленнее.
Я попробовал несколько простых тестовых случаев, чтобы определить медленную часть ЦП, но тестовые случаи выполнялись с одинаковым временем, даже на медленном ядре №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];
}
}
}
Вопрос: Почему одно ядро ЦП будет медленнее других, и какая часть ЦП вызывает такое замедление?
РЕДАКТИРОВАТЬ: Дальнейшее тестирование показало некоторые Гейзенбаг поведение. Когда я явно устанавливаю привязку к процессору, мое приложение не замедляется на ядре № 2. Однако, если он выберет работу на ядре № 2 без явно установленной привязки процессора, то приложение будет работать примерно на 10% медленнее. Это объясняет, почему в моих простых тестовых примерах не было такого же замедления, поскольку все они явно устанавливали привязку процессора. Таким образом, похоже, что существует какой-то процесс, который любит жить на ядре № 2, но он исчезает, если установлено сходство процессора.
Итог: Если вам нужен точный тест однопоточной программы на многоядерном компьютере, то обязательно установите привязку процессора.