Почему люди рекомендуют параметр -j3 для make при наличии двухъядерного процессора?

18

В Gentoo Linux можно установить MAKEOPTSпеременную, /etc/portage/make.confчтобы указать, makeсколько заданий должно выполняться параллельно при сборке пакетов. Поскольку у меня двухъядерный процессор, я наивно решил использовать -j2опцию: одна работа на ядро, поэтому у обоих есть чем заняться. «Проблема» в том, что существует множество ссылок, которые говорят пользователям, имеющим двухъядерный процессор, -j3вместо этого устанавливать опцию. Некоторые из них:

Например, руководство Gentoo гласит:

Хороший выбор - это количество процессоров (или процессорных ядер) в вашей системе плюс один, но это правило не всегда идеально.

Но что является обоснованием для правила «ЦП + 1»? Почему дополнительная работа?

Страница man make.conf (5) даже говорит:

Предлагаемые настройки: между CPU + 1 и 2 * CPU + 1.

Я также прочитал раздел 5.4 (Параллельное выполнение) на makeинформационной странице и makeобъяснение справочной страницы для -jопции, но, похоже, там нет ответов.

Франческо Турко
источник

Ответы:

13

Нет простого правила, которое всегда работает. Люди могут порекомендовать конкретную фигуру, потому что они экспериментировали с конкретной компиляцией на конкретной машине, и это было лучшим вариантом, или потому, что они следовали некоторым рассуждениям, которые могут иметь или не иметь какое-то отношение к реальности.

Если вы наделены большим количеством оперативной памяти, то ограничивающим фактором при длительной компиляции будет время процессора. Тогда одна задача на процессор плюс одна ожидающая задача для этих случайных блоков ввода / вывода - это хорошая настройка. Это делает его -j3для двухъядерного процессора (или, точнее, для двухпроцессорного компьютера - если каждое ядро ​​является многопоточным, это будет 4 процессора, так -j5).

Если у вас очень мало оперативной памяти, то ограничивающим фактором может быть то, что у вас не может быть много одновременных заданий, иначе они будут заставлять друг друга менять местами. Например, если вы не можете удобно разместить два экземпляра компилятора в памяти, это make -j2может быть медленнее, чем make. Так как это зависит от того, сколько процессов компилятора вы можете разместить в оперативной памяти, нет никакого способа получить общую цифру.

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

Жиль "ТАК - прекрати быть злым"
источник
Я не знал, что если ядра ЦП являются многопоточными, то каждое из них считается двумя. В любом случае, похоже, что мой процессор не поддерживает Hyper Threading.
Франческо Турко
Я принял этот ответ. В любом случае, я решил придерживаться -j2своей системы. Это связано с тем, что я попытался установить и то, gccи другое firefoxс настройками от ( -j1до -j510 команд emerge), и кажется, что пока -j2оно определенно быстрее, чем -j1остальные три параметра находятся на одном уровне -j2.
Франческо Турко
7

Я предполагаю, что это своего рода эвристика - позволить makeзапускать CPUs + 1процессы, чтобы убедиться, что:

  1. не было бы разрыва между рабочим процессом, который только что закончился, и рабочим, еще не запущенным - что-то вроде очереди на предварительное заполнение.
  2. не было бы слишком много конкурирующих процессов, чтобы вносить заметные издержки с этим предварительным заполнением очереди выполнения.

Но, опять же, это эвристично, и руководство FreeBSD по-прежнему рекомендует make -j4 использовать один процессор.

poige
источник
5

Как правило, есть причины для запуска большего количества заданий, чем количества ядер. Для компиляции C с использованием gcc, если -pipe не определен в опциях gcc, он выполняет свои действия (предварительную обработку, первый запуск, оптимизацию и сборку) в последовательности, используя временные файлы; -pipe меняет это на использование каналов между подпроцессами. (Добавление -pipe используется по умолчанию, например, для FreeBSD, но не является традиционным для Linux.) Таким образом, если у вас есть 2 ядра и разрешено 2 задания параллельно, они потратят некоторое время на дисковый ввод-вывод. Рекомендация добавить 1 вакансию, похоже, связана с этой спецификой. Но чтобы получить окончательный ответ, вы должны найти, кто и когда добавил эту рекомендацию, и спросить его :) или спросить в списке рассылки Gentoo devels.

Netch
источник
2

В основном это число - то, что авторы называют здравым смыслом. В лучшем случае, это хорошее предположение. Насколько я знаю, процесс make, который запускается при вводе текста, makeуже подсчитан, так что -j3вы можете получить основной процесс, ожидающий, пока два других компилируются.

Однако, когда я использовал Gentoo, эмпирическое правило было <#cpus>*2 + 1.

Все зависит от того, что ваши куриные следы, чайные листья или волшебный шар рассказывают вам о дисковых операциях ввода-вывода, которые необходимо выполнить, и о планировании вашего текущего ядра Linux. [начать ядро ​​этого поста] Из моего личного опыта ( -jне является специфичным для Gentoo) все, что находится между #cpus + 1 и #cpus * 2 +1, дает хорошие результаты [закончите ядро ​​этого поста], и в среднем вы вряд ли заметите какие-либо различия. Процессоры и ядра довольно хороши в наши дни.

НО все это меняется, когда: а) вы фактически используете более одного блока для компиляции (du'h) или б) разрабатываете свой собственный код

Более высокий -jатрибут с большей вероятностью покажет ранее неизвестные зависимости.

И на заметку: не указывайте количество ядер, а количество параллельных потоков, которые занимают процессоры. (Hypertheading!)

Bananguin
источник