Подтвердить что ты не робот

Как запускать процессы с помощью bash на нескольких ядрах?

У меня есть простой bash script, который передает вывод одного процесса другому. А именно:.

dostuff | filterstuff

Бывает, что в моей Linux-системе (openSUSE, если это имеет значение, ядро ​​2.6.27) эти оба процесса работают на одном ядре. Однако выполнение различных процессов на разных ядрах - это политика по умолчанию, которая в этом случае не запускается.

Какой компонент системы отвечает за это и что мне делать, чтобы использовать многоядерную функцию?

Примечание, что в ядре 2.6.30 такой проблемы нет.

Разъяснение. Следуя рекомендациям Денниса Уильямсона, я позаботился о том, чтобы потоковые процессы действительно выполнялись на одном процессоре, Планировщик Linux, который обычно делает действительно хорошую работу, на этот раз не делает этого.

Я полагаю, что что-то в bash не позволяет ОС делать это. Дело в том, что мне нужно портативное решение для многоядерных и одноядерных машин. Решение taskset , предложенное Деннисом Уильямсоном, не будет работать на одноядерных машинах. В настоящее время я использую:,

dostuff | taskset -c 0 filterstuff 

но это кажется грязным взломом. Может ли кто-нибудь предложить лучшее решение?

4b9b3361

Ответ 1

Предположим, что dostuff работает на одном CPU. Он записывает данные в канал, и данные будут находиться в кеше на этом CPU. Поскольку filterstuff читает из этого канала, планировщик решает запустить его на одном CPU, так что его входные данные уже находятся в кеше.

Если ваше ядро ​​построено с помощью CONFIG_SCHED_DEBUG=y,

# echo NO_SYNC_WAKEUPS > /sys/kernel/debug/sched_features

должен отключить этот класс эвристик. (См. /usr/src/linux/kernel/sched_features.h и /proc/sys/kernel/sched_* для других планировщиков планировщика.)

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

Ответ 2

Попробуйте установить сродство к процессору (процессору):

taskset -c 0 dostuff | taskset -c 1 filterstuff

Edit:

Попробуйте этот эксперимент:

  • создайте файл с именем proctest и chmod +x proctest с этим в качестве содержимого:

    #!/bin/bash
    while true
    do
      ps
      sleep 2
    done  
    
  • запустить этот запуск:

    ./proctest | grep bash
    
  • в другом терминале, начните сверху - убедитесь, что он сортирует по% CPU
  • пусть он опустится на несколько секунд, затем закройте
  • выполните команду ps u
  • запустите top -p со списком PID из самых высоких процессов, скажем 8 из них, из списка слева на выведенном top плюс те, что указаны для proctest и grep > , которые были перечислены ps - все разделены запятыми, например (порядок не имеет значения):

    top -p 1234, 1255, 1211, 1212, 1270, 1275, 1261, 1250, 16521, 16522
    
  • добавьте поле процессора - нажмите f, затем j, затем Space
  • установите сортировку в PID - нажмите Shift + f, затем a, затем Space
  • необязательно: нажмите Shift + H, чтобы включить просмотр потока
  • необязательно: нажмите d и введите .09 и нажмите Enter, чтобы установить короткое время задержки
  • теперь, когда процессы переходят из процессора в процессор, вы должны видеть proctest и grep отскок, иногда на одном процессоре, иногда на разных

Ответ 3

Планировщик Linux разработан, чтобы обеспечить максимальную пропускную способность, а не делать то, что вы считаете лучшим. Если вы работаете с процессами, связанными с каналом, то, по всей вероятности, один из них блокирует другой, затем они меняются. Запуск их на отдельных ядрах достигнет мало или ничего, так что это не так.

Если у вас есть две задачи, которые действительно готовы к запуску на CPU, я ожидаю, что они будут запланированы на разных ядрах (в какой-то момент).

Я предполагаю, что происходит то, что dostuff запускается до тех пор, пока буфер буфера не будет заполнен, и в этот момент он больше не сможет работать, поэтому процесс "filterstuff" выполняется, но он выполняется за такое короткое время, когда dostuff doesn 't откладывается до тех пор, пока фильтр не завершит фильтрацию всего буфера для труб, после чего снова будет добавлен dostuff.