GNU make: должно ли количество заданий равняться количеству ядер процессора в системе?
Кажется, есть некоторые разногласия по поводу того, должно ли количество заданий в GNU make быть равно количеству ядер, или если вы можете оптимизировать время сборки, добавив одно дополнительное задание, которое может быть поставлено в очередь, пока другие "работают".
лучше использовать -j4 или -j5 на четырехъядерной системе?
вы видели (или делали) какой-либо бенчмаркинг, который поддерживает один или другой?
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 hwpstatebob@Moses:/archive4$ free total used free shared buffers cached Mem: 3991304 3834564 156740 0 519220 2515308
Так же, как ref:
С на LKD:
где n-количество заданий для создания. Обычная практика заключается в создании одного или двух заданий на процессор. Например, на двухпроцессорной машине можно сделать
$ make j4
по моему опыту, при добавлении дополнительных заданий должны быть некоторые преимущества производительности. Это просто потому, что дисковый ввод-вывод является одним из горлышек бутылки, кроме процессора. Однако это не легко решить, на количество дополнительных заданий, как это очень взаимосвязано с количеством ядер и типов используемого диска.
Comments