GNU make: должно ли количество заданий равняться количеству ядер процессора в системе?



Кажется, есть некоторые разногласия по поводу того, должно ли количество заданий в GNU make быть равно количеству ядер, или если вы можете оптимизировать время сборки, добавив одно дополнительное задание, которое может быть поставлено в очередь, пока другие "работают".



лучше использовать -j4 или -j5 на четырехъядерной системе?



вы видели (или делали) какой-либо бенчмаркинг, который поддерживает один или другой?

528   7  

7 ответов:

Я бы сказал, что лучше всего сделать, это проверить его самостоятельно на вашей конкретной среде и рабочей нагрузки. Похоже, что существует слишком много переменных (размер / количество исходных файлов, доступная память, кэширование диска, расположены ли ваши исходные каталоги и системные заголовки на разных дисках и т. д.) для ответа на один размер подходит всем.

мой личный опыт (на 2-ядерном MacBook Pro) заключается в том, что-j2 значительно быстрее, чем-j1, но помимо этого (-j3,- j4 и т. д.) там нет измеримых ускорение. Поэтому для моей среды "jobs == количество ядер" кажется хорошим ответом. (YMMV)

Я запустил свой домашний проект на своем 4-ядерном ноутбуке с hyperthreading и записал результаты. Это довольно компилятор-тяжелый проект, но он включает в себя модульный тест 17,7 секунд в конце. Компиляции не очень интенсивны; есть очень много доступной памяти, и если не все остальное находится на быстром SSD.

1 job        real   2m27.929s    user   2m11.352s    sys    0m11.964s    
2 jobs       real   1m22.901s    user   2m13.800s    sys    0m9.532s
3 jobs       real   1m6.434s     user   2m29.024s    sys    0m10.532s
4 jobs       real   0m59.847s    user   2m50.336s    sys    0m12.656s
5 jobs       real   0m58.657s    user   3m24.384s    sys    0m14.112s
6 jobs       real   0m57.100s    user   3m51.776s    sys    0m16.128s
7 jobs       real   0m56.304s    user   4m15.500s    sys    0m16.992s
8 jobs       real   0m53.513s    user   4m38.456s    sys    0m17.724s
9 jobs       real   0m53.371s    user   4m37.344s    sys    0m17.676s
10 jobs      real   0m53.350s    user   4m37.384s    sys    0m17.752s
11 jobs      real   0m53.834s    user   4m43.644s    sys    0m18.568s
12 jobs      real   0m52.187s    user   4m32.400s    sys    0m17.476s
13 jobs      real   0m53.834s    user   4m40.900s    sys    0m17.660s
14 jobs      real   0m53.901s    user   4m37.076s    sys    0m17.408s
15 jobs      real   0m55.975s    user   4m43.588s    sys    0m18.504s
16 jobs      real   0m53.764s    user   4m40.856s    sys    0m18.244s
inf jobs     real   0m51.812s    user   4m21.200s    sys    0m16.812s

основные результаты:

  • масштабирование до количества ядер увеличивает производительность почти линейно. Реальное время снизилось с 2,5 минут до 1,0 минута (2,5 раза быстрее), но время, затраченное на компиляцию, увеличилось с 2,11 до 2,50 минуты. Система почти не заметила дополнительной нагрузки в этом бите.
  • масштабирование от количества ядер до количества потоков значительно увеличило пользовательскую нагрузку с 2,50 минут до 4,38 минут. Это почти удвоение, скорее всего, потому, что другие экземпляры компилятора хотели использовать те же ресурсы ЦП в то же время. Система становится немного более загруженной с запросами и переключением задач, в результате чего она перейти к 17.7 секунд времени. Преимущество составляет около 6,5 секунд на время компиляции 53,5 секунд, что делает для 12% ускорения.
  • масштабирование от количества потоков до двойного количества потоков не дало значительного ускорения. Время в 12 и 15, скорее всего статистические аномалии, которые можно игнорировать. Общее затраченное время увеличивается так же незначительно, как и системное время. Оба, скорее всего, из-за увеличения переключения задач. В этом нет никакой пользы.

мой угадайте прямо сейчас: если вы делаете что-то еще на вашем компьютере, используйте количество ядер. Если вы не используйте нитей. Превышение его не показывает никакой пользы. В какой-то момент они станут ограниченной памятью и свернутся из-за этого, что сделает компиляцию намного медленнее. Строка " inf " была добавлена гораздо позже, что дало мне подозрение, что для заданий 8+ было некоторое тепловое дросселирование. Это показывает, что для этого размера проекта нет ограничения памяти или пропускной способности в действительности. Это небольшой проект хотя, учитывая 8 ГБ памяти для компиляции.

Я, лично, использую make -j n где n - "количество ядер" + 1.

Я не могу, однако, дать научное объяснение: я видел много людей, использующих те же настройки, и они дали мне довольно хорошие результаты до сих пор.

в любом случае, вы должны быть осторожны, потому что некоторые make-цепи просто не совместимы с , и может привести к неожиданным результатам. Если вы испытываете странные ошибки зависимости, просто попробуйте make без --jobs.

в конечном счете, вам придется сделать некоторые тесты, чтобы определить лучшее число для использования для вашей сборки, но помните, что процессор не единственный ресурс, который имеет значение!

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

и тогда у вас есть" реальные " ядра против гиперпоточности. Вы можете или не можете извлечь выгоду из нерестовых заданий для каждого гиперпотока. Опять же, вам придется проверить, чтобы узнать.

Я не могу сказать, что я специально пробовал #ядер + 1, но в нашей системе (процессор i7 940, 4 hyperthreaded ядер, много оперативной памяти, и VelociRaptor накопители) и нашей сборки (масштабные построения C++ это поочередно CPU и I / O связаны) существует очень мало разницы между-j4 и-j8. (Это может быть на 15% лучше... но далеко не в два раза лучше.)

Если я уйду на обед, я буду использовать-j8, но если я хочу использовать свою систему для чего-либо еще, пока она строится, я буду использовать меньшее число. :)

я только что получил Athlon II X2 Regor proc с Foxconn M / B и 4 ГБ памяти G-Skill.

я поставил свои "cat/proc / cpuinfo" и "free" в конце этого, чтобы другие могли видеть мои спецификации. Это двухъядерный Athlon II x2 с 4 ГБ оперативной памяти.

uname -a on default slackware 14.0 kernel is 3.2.45.

я загрузил следующий шаг kernel source (linux-3.2.46) в /archive4;

извлекли его (tar -xjvf linux-3.2.46.tar.bz2);

диск D в директорию (cd linux-3.2.46);

и скопировал ядро по умолчанию конфигурации по (cp /usr/src/linux/.config .);

используется make oldconfig для подготовки конфигурации ядра 3.2.46;

затем побежал делать с различными заклинаниями-jX.

я проверил тайминги каждого запуска, выдав команду make после команды time, например, время сделать -и J2'. Между каждым запуском я 'rm-rf' дерево linux-3.2.46 и повторно извлек его, скопировал значение по умолчанию /usr/src/linux/.config в каталог, запустил make oldconfig, а затем снова сделал мой тест "make-jX".

равнина "make":

real    51m47.510s
user    47m52.228s
sys     3m44.985s
bob@Moses:/archive4/linux-3.2.46$

как и выше, но с make-j2

real    27m3.194s
user    48m5.135s
sys     3m39.431s
bob@Moses:/archive4/linux-3.2.46$

как и выше, но с make-j3

real    27m30.203s
user    48m43.821s
sys     3m42.309s
bob@Moses:/archive4/linux-3.2.46$

как и выше, но с make-j4

real    27m32.023s
user    49m18.328s
sys     3m43.765s
bob@Moses:/archive4/linux-3.2.46$

как и выше, но с make-j8

real    28m28.112s
user    50m34.445s
sys     3m49.877s
bob@Moses:/archive4/linux-3.2.46$

' cat /proc/cpuinfo ' дает:

bob@Moses:/archive4$ cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 6
model name      : AMD Athlon(tm) II X2 270 Processor
stepping        : 3
microcode       : 0x10000c8
cpu MHz         : 3399.957
cache size      : 1024 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmo
v pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rd
tscp lm 3dnowext 3dnow constant_tsc nonstop_tsc extd_apicid pni monitor cx16 p
opcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowpre
fetch osvw ibs skinit wdt npt lbrv svm_lock nrip_save
bogomips        : 6799.91
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

processor       : 1
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 6
model name      : AMD Athlon(tm) II X2 270 Processor
stepping        : 3
microcode       : 0x10000c8
cpu MHz         : 3399.957
cache size      : 1024 KB
physical id     : 0
siblings        : 2
core id         : 1
cpu cores       : 2
apicid          : 1
initial apicid  : 1
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmo
v pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rd
tscp lm 3dnowext 3dnow constant_tsc nonstop_tsc extd_apicid pni monitor cx16 p
opcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowpre
fetch osvw ibs skinit wdt npt lbrv svm_lock nrip_save
bogomips        : 6799.94
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate
'' дает:
bob@Moses:/archive4$ free
             total       used       free     shared    buffers     cached
Mem:       3991304    3834564     156740          0     519220    2515308

Так же, как ref:

С на LKD:

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

$ make j4

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

Comments

    Ничего не найдено.