В качестве предисловия я использую Debian Wheezy с ядром 3.2 на чипсете AMD64. В моей машине два ядра Xeon E5-2690. Я настроил параметры загрузки так, чтобы все ядра одного процессора были выделены для одного процесса. Для этого в grub я установил команду isolcpus = 8,9,10,11,12,13,14,15.
Все идет нормально. Теперь предположим, что я хочу использовать изолированные процессоры для данной команды, для простоты я просто использую простой бесконечный цикл:
$ taskset -c 8-15 bash -c 'пока верно; эхо-привет> / dev / null; сделано' &
Пока все хорошо, top показывает, что ядро 8 загружается почти до 100%. Теперь предположим, что я снова запускаю эту команду:
$ taskset -c 8-15 bash -c 'пока верно; эхо-привет> / dev / null; сделано' &
Теперь наверху показано, что ядра 9-15 остаются в режиме ожидания, а два процесса совместно используют ядро 8. Если вместо этого я сделаю следующее:
$ taskset -c 8 bash -c 'пока верно; эхо-привет> / dev / null; сделано' &
$ taskset -c 9 bash -c 'пока правда; эхо-привет> / dev / null; сделано' &
Ядра 8 и 9 загружаются на 100% должным образом. Это применимо только к изолированному процессору, поскольку тот же набор задач с ядрами 1-7 правильно распределяет процессы по соответствующим ядрам. Кроме того, «taskset -p» показывает, что маска соответствия для 8-15 процессов установлена правильно. Похоже, что планировщик ядра отказывается использовать что-либо, кроме самого нижнего ядра, указанного в маске сродства изолированного процессора.
Обычно это не будет иметь большого значения с моими приведенными выше примерами, просто укажите отдельные ядра для каждого процесса. Однако я хочу запустить многопоточное приложение на выделенном процессоре. Я хочу указать базовый набор и автоматически использовать пул потоков без необходимости индивидуального сброса привязки процессора для каждого отдельного порожденного потока.
Кто-нибудь знает, как заставить планировщик выдавать мне более одного ядра из набора Isolcpu?
После дня разочарований я нашел решение. Такое поведение кажется артефактом алгоритма планировщика ядра по умолчанию (SCHED_OTHER для этого дистрибутива / ядра). Изменение процесса на другой алгоритм устраняет проблему, изолированные процессоры адекватно используются во всех процессах / потоках.
В итоге я использовал SCHED_RR, но я также протестировал SCHED_FIFO и SCHED_IDLE, оба из которых, похоже, работают. Процесс можно запустить по альтернативному алгоритму с помощью утилиты chrt:
$ sudo chrt -r 1 [команда]
(Если вы хотите работать без полномочий root, вы можете использовать утилиту setcap, чтобы включить CAP_SYS_NICE в двоичном файле, связанном с командой)