Почему одно ядро ​​ЦП работает медленнее, чем другие?

Я тестировал большое научное приложение и обнаружил, что иногда оно работает на 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, но он убирается, если установлена ​​привязка к процессору.

Итог. Если вам нужен точный эталонный тест однопоточной программы на многоядерном компьютере, обязательно установите привязку к процессору.


person Edi H    schedule 13.05.2009    source источник


Ответы (4)


У вас могут быть приложения, которые решили быть подключенными к одному и тому же процессору (CPU Affinity).

Операционные системы часто хотели бы работать на одном и том же процессоре, поскольку все их данные могут кэшироваться в одном и том же кэше L1. Если вам случится запустить свой процесс на том же ядре, на котором ваша ОС выполняет большую часть своей работы, вы можете испытать эффект замедления производительности вашего процессора.

Похоже, что какой-то процесс хочет придерживаться одного и того же процессора. Сомневаюсь, что это аппаратная проблема.

Это не обязательно должна делать ваша ОС, это может делать какой-то другой фоновый демон.

person Kekoa    schedule 13.05.2009

Большинство современных процессоров имеют отдельное дросселирование каждого ядра процессора из-за перегрева или функций энергосбережения. Вы можете попробовать отключить энергосбережение или улучшить охлаждение. Или, может быть, ваш процессор плохой. На моем i7 я получаю примерно на 2-3 градуса разные температуры ядра из 8 заявленных ядер в «сенсорах». При полной загрузке есть еще колебания.

person krosenvold    schedule 13.05.2009

Другая возможность заключается в том, что процесс переносится с одного ядра на другое во время работы. Я бы предложил установить привязку процессора к «медленному» ядру и посмотреть, будет ли он таким же быстрым.

Много лет назад, еще до появления многоядерных процессоров, я купил себе двухпроцессорный процессор Athlon MP для «веб-разработки». Внезапно мои веб-серверы Plone/Zope/Python замедлились до минимума. Поиск в Google показал, что интерпретатор CPython имеет глобальную блокировку интерпретатора, но потоки Python поддерживаются потоками ОС. Потоки ОС были равномерно распределены между ЦП, но только один ЦП может одновременно получить блокировку, поэтому все остальные процессы должны были ждать.

Установка привязки ЦП Zope к любому ЦП устранила проблему.

person shapr    schedule 15.05.2009

Я наблюдал нечто подобное на своем ноутбуке Haswel. В системе было тихо, X не работал, только терминал. Выполнение одного и того же кода с другой опцией numactl --physcpubin дало одинаковые результаты на всех ядрах, кроме одного. Менял частоту ядер на Турбо, на другие значения, ничего не помогло. Все ядра работали с ожидаемой скоростью, кроме одного, которое всегда работало медленнее остальных. Этот эффект пережил перезагрузку.

Я перезагрузил компьютер и отключил HyperThreading в BIOS. Когда он вернулся в сеть, он снова был в порядке. Затем я включил HyperThreading, и до сих пор все в порядке.

Биззаре. Без понятия, что это может быть.

person angainor    schedule 28.11.2014