Как на самом деле работает опция "-j"? - PullRequest
20 голосов
/ 03 марта 2010

На страницах man:

-j [jobs], --jobs [= jobs] Указывает количество заданий (команд), которые должны выполняться одновременно.Если есть несколько опций -j, последний действует.Если опция -j указана без аргумента, make не будет ограничивать количество заданий, которые могут выполняться одновременно.

Я знаю, что для определения правил, которые являются независимыми, используется зависимость от графика.

Я хотел бы знать, как построен этот график, и понять, какие критерии используются.

спасибо.

Ответы [ 2 ]

24 голосов
/ 03 марта 2010

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

Например,

Вершины для файлов .c и .h не будут иметь входящих ребер. Эти файлы являются вашими исходными файлами и не нуждаются в сборке.

Затем выполняется топологическая сортировка на графике для определения порядка выполнения. Из Википедии:

Каноническое применение топологической сортировки (топологический порядок) заключается в планировании последовательности заданий или заданий; Алгоритмы топологической сортировки впервые были изучены в начале 1960-х годов в контексте технологии PERT для планирования в управлении проектами (Jarnagin 1960). Задания представлены вершинами, и существует грань от x до y, если задание x должно быть завершено до того, как задание y может быть запущено (например, при стирке белья стиральная машина должна завершить работу до того, как мы сохнем). Затем топологическая сортировка дает порядок выполнения заданий.

Суть топологической сортировки состоит в том, чтобы найти вершины без входящих ребер (без зависимостей) и поставить их на первое место. Затем удалите их из графика. Теперь у вас будет новый набор вершин без входящих ребер (без зависимостей). Это следующие. И так до тех пор, пока не закончите. (Если вы когда-либо достигнете точки, когда таких вершин не существует, то граф зависимостей содержит цикл, который является ошибочным условием.)

В типичном Makefile это означает, что вы сначала создадите исходные файлы (ничего не нужно делать). Затем объектные файлы, которые зависят от этих исходных файлов. Затем библиотеки и исполняемые файлы, созданные из этих объектных файлов.

При обычной непараллельной работе make будет просто выбирать одну цель на каждой итерации и строить ее. Когда он параллельный, он будет захватывать столько целей без зависимостей, сколько может, и строить их параллельно, до количества разрешенных одновременных заданий.

Таким образом, когда make дойдет, скажем, до шага объектного файла, у него будет большое количество вершин в графе, которые не имеют входных ребер. Он знает, что может создавать объектные файлы параллельно, и поэтому он создает n копий gcc для создания объектных файлов.

3 голосов
/ 03 марта 2010

Я подозреваю, что вы ожидаете чего-то более волшебного, чем на самом деле здесь. Makefiles содержат строки вроде:

target: prereq1 prereq2 prereq3 ...

Это определяет отношения между файлами в системе; на языке графа каждое слово в строке, разделенное пробелами, неявно объявляет узел в графе, и создается направленный край между каждым из узлов слева от двоеточия и каждым из узлов справа от двоеточия. , указывая от последнего к первому.

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...