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