В рамках исследовательского проекта Parallel GCC началась работа по добавлению в GCC возможности, позволяющей разделять процесс компиляции на несколько параллельно выполняемых потоков. В настоящее время для повышения скорости сборки на многоядержных системах на уровне утилиты make применяется запуск отдельных процессов компилятора, каждый из которых выполняет сборку отдельного файла с кодом. Новый проект экспериментирует с обеспечением распараллеливания на уровне компилятора, что потенциально позволит повысить эффективность работы на многоядерных системах...Подробнее: https://www.opennet.ru/opennews/art.shtml?num=51491
> Тесты на системе с CPU Intel Core i5-8250UЭто всё, что надо знать про данные исследования. Сферические теоретические кони в вакууме. Зачем оно, вообще, если сборка любого мало-мальски крупного проекта и так отлично распараллеливается тупо запуском множества процессов компиляции.
Множество процессов компиляции неэффективно по памяти
Зато более эффективно по процессору, а память можно докупить
И процессор можно докупить. Видимо только время нельзя докупить ...
Память ныне стоит сущие копейки. Городить при этом какой-то огород, перепахивая кусками компилятор, в котором и так чёрт ногу сломит... работа ради работы, без цели и смысла.
То есть, никто не понимает, что разрабы пытаются удешевить (по времени, танкисты, по времени) управление памятью и ЦП вместо того, чтобы при компиляции генерировать кучу ненужных системных вызовов, только отнимающих время, и упираться по потолку производительности в шедулер? Пздц вы тупые, откуда вам вообще сюда выпустили?
> То есть, никто не понимает, что разрабы пытаются удешевить (по времени, танкисты,
> по времени) управление памятью и ЦП вместо того, чтобы при компиляции
> генерировать кучу ненужных системных вызовов, только отнимающих время, и упираться по
> потолку производительности в шедулер? Пздц вы тупые, откуда вам вообще сюда
> выпустили?Штопрастите?
Купи им 9900K
Компиляция, тем более распараллеленная гораздо лучше пойдет на R9 3950X.
> Компиляция, тем более распараллеленная гораздо лучше пойдет на R9 3950X.Вот да. И даже никакого дорогостоящего перепахивания компилятора не потребуется :D, а эффект будет куда выше, чем от перепахивания для всяких мобильных i5.
В Сях нужно не парралелить, а кешировать заголовки
Студни-хипсторы решили помучить поциента перед его окончательной кончиной.Шланг смотрит на всё это со снисходительной улыбкой
Шланг смотреть с улыбкой не может, у него те же болячки. У него так же делается "распаралеливание" как и у GCC (запуск множества процессов шланга).
а чем это плохо? не модно ?
Или нужно еще сильнее дергать головки у диска - что бы скорость упала.
Это плохо лишними сисколлами и отсутствием нормального интерпроцессного взаимодействия. Тредами рулить удобнее и дешевле, чем полноценными инстансами.
Например, для целей CI, когда время сборки оказывается более существенным, чем при единичном запуске...Мне другое непонятно -- при всей востребованности распараллеливания сборки _единичной_ цели как они собираются это увязывать с распараллеливанием средствами того же make? Пока напрашивается разве что массовый переход сборочных систем на использование -l вместо -j как минимум в нормальном make, но при изолированных окружениях это потребует пробрасывания как минимум настоящего /proc/loadavg в чруты.
Мы обдумывали нечто перекликающееся в плане оптимизации плотности использования сборочных узлов в условиях, когда параллельно запускаемые сборки могут параллелиться, а могут и нет. Пока применяю gnu parallel для некоторых задач, но в случае "девятого вала" хорошо параллелящихся тяжёлых сборок узлам бывает грустно.
А сейчас представил себе параллелизацию третьего порядка (пакеты, цели, и затем внутренняя по каждой цели вдобавок) -- для aarch64 это было бы полезно вотпрямщас, на ppc64le с его горой потоков тоже бы уже пригодилось, но как с этим всем управляться -- пока вопрос.
Тоже сразу возник вопрос про связь с make -j. Пока кажется, что параллелизация через make будет эффективнее. Сколько раз смотрел на загрузку ядер при сборке make -j по количеству ядер, всегда все ядра на 100% использовались. А тут что-то идеального повышения производительности не видно пока.
Да нет никакой связи с make -j кроме чистой детерминированности процесса сборки - когда компиляция одного куска кода зависит от результата компиляции другого.Вся суть многопоточной, а не многопроцессной компиляции в том, чтобы родственные нити выполнялись на одном или соседних ядрах с общим кэшем инструкций и данных - так уменьшается вероятность перезагрузки кэшей и в разы ускоряется доступ к данным.
Планировщики современных операционных систем учитывают особенности многоядерности и топологию их вычислительных модулей. Для Ryzen 3xxx даже специальные исправления выходили по привязыванию отдельных нитей, использующих общие данные, к одному CCX (каждая нить исполняется на "своём" ядре внутри CCX) - что исключает операции по синхронизации кэшей отдельных CCX и увеличивает быстродействие.
> Вся суть многопоточной, а не многопроцессной компиляции в том, чтобы родственные нити
> выполнялись на одном или соседних ядрах с общим кэшем инструкций и
> данных - так уменьшается вероятность перезагрузки кэшей и в разы ускоряется
> доступ к данным.Простите за такую подробность, но процессор это не виртуальная машина Джавы, он ничего не знает про процессы. Если образ одного и того же исполняемого файла отображается в разные адресные пространства, то физические страницы с кодом должны быть везде одни и те же, соответственно и кеш инструкций когерентен.
Что касается данных, я не просто возьму из головы некие "разы", а поделю 1000мб, которые процесс компилятора занял в памяти под AST (где Т означает не последовательно расположенные данные, а дерево), на объём кэша, и скажу, что вероятность не изменилась.
>> Вся суть многопоточной, а не многопроцессной компиляции в том, чтобы родственные нити
>> выполнялись на одном или соседних ядрах с общим кэшем инструкций и
>> данных - так уменьшается вероятность перезагрузки кэшей и в разы ускоряется
>> доступ к данным.
> Простите за такую подробность, но процессор это не виртуальная машина Джавы, он
> ничего не знает про процессы. Если образ одного и того же
> исполняемого файла отображается в разные адресные пространства, то физические страницы
> с кодом должны быть везде одни и те же, соответственно и
> кеш инструкций когерентен.Зато новый планировщик знает об особенностях архитектуры процессора и какую нить прицепить к какому ядру среди нескольких CCX. В Ryzen общий кэш распределённый между CCX, а скорость доступа данных нити, привязанной к одному ядру, зависит от того, в каком участке кэша находятся её и родственной нити данные. Если в участке кэша, связанным с другим CCX, то нужна пересылка этих данных оттуда по протоколу обмена данными между CCX, принаджежащих разным CCD, с задействованием I/O-чиплета — работа замедляется на время этой чисто аппаратной операции. Если две нити работают на разных ядрах одного CCX, то задержки не возникает — их разделяемые данные находятся в участке кэша CCX.
"В один блок CCX объединяется 4 ядра и 16 Мбайт общей кеш-памяти третьего уровня. Пара CCX располагается на одном 7-нм полупроводниковом кристалле и формирует процессорный чиплет, получивший аббревиатуру CCD (Core Complex Die). В зависимости от того, о каком процессоре семейства Ryzen 3000 идёт речь, он может состоять либо из двух, либо из трёх чиплетов. В процессорах с числом ядер восемь и менее применяется один CCD-чиплет и один I/O-чиплет. В процессорах с числом ядер более восьми CCD-чиплетов становится уже два. Однако нужно понимать, что процессор при этом всё равно остаётся единым целым. За счёт того, что в любых Ryzen 3000 контроллер памяти находится в I/O-чиплете и он всего один, любое из ядер может гладко обращаться к любым её областям: никаких NUMA-конфигураций, которые портили жизнь владельцам процессоров Threadripper, в случае Zen 2 не будет."
С процессами это осуществить сложнее, так как нити в раздельных процессах имеют защиту памяти и нуждаются в отдельном протоколе обмена межпроцессного взаимодействия (IPC). Это оверхед.
Системы с общей памятью (потоки и т.д.) хороши далеко не для всех задач. Задачи трансляции-компоновки хорошо авто-параллелятся далеко не во всех случаях. ))
А при чём тут CI и цели? Тут речь идёт о внутреннем распараллеливании сборки одного-единственного файла. Зачем это - ума не приложу. Любителей собирать многомегабайтные монолиты вроде не осталось.
>Новый проект экспериментирует с обеспечением распараллеливания на уровне компилятора, что потенциально позволит повысить эффективность работы на многоядерных системах.Потоки? Многоядерные системы? В 2019? Да не это бред какой-то
Если бы они сущестовали то наверняка их поддержка появилась бы в GNU HURD
Интересно как мы так раньше всю жизнь компилировали что сабж был не нужен.
Медленно
Кто о чём а вшивый о бане. Анониму видимо невдамёк, что Hurd забросили сразу после первого выпуска Linux. То, что они делают сейчас -- предсмертные конвульсии. Какие-то жалкие попытки 1.5 анонимов допилить ядро, примерно то же, что происходит с React OS.
А что там у реакт ОС?
Да, но пока нет.
Интересно, как оно грузит ядра. Ибо если все 4/8 ядра на все 100%, но ускоряет суммарно в 2,5 раза, то получается, наверняка, энергетически невыгодно.
Судя по тексту в статье распараллелили не все этапы компиляции
man "Закон Амдала"Да уж наверняка не выгодно, но на настольных компах на это особого внимания не обращают. Быстрее бы работало.
Так это оптимизация не энергозатрат, а времени выполнения.
Грузить ЦП на 100% всегда выгодно
Вы не правы. По крайней мере на процессорах Intel серии U это не так из-за термального режима, на который они конструктивно рассчитаны, и соответственно thermal throttling'а. Другими словами - ограничив нагрузку до 80-90%, получаем в среднем меньший вольтаж и более быструю результирующую компиляцию из-за меньшего троттлинга (штеуд перестраховывается? может быть). Полагаю, с штатными кулерами AMD, которые идут в комплекте с последними Ryzen - всё так же, но менее выражено в %.
>По крайней мере на процессорах Intel серии U это не так из-за термального режима, на который они конструктивно рассчитаны, и соответственно thermal throttling'а. Другими словами - ограничив нагрузку до 80-90%Я говорю про нормальные процессоры, а не обрезки, максимум которых - просмотр ютуба
Какой Ютуб очнитесь это текстовые стратегии и консольный режим для терминалов из 80-х всякие там имаксы и прочая чепушень
Несмотря на распараллеливание в make&Co я, похоже, знаю, почему им пришлось взяться за компилятор. Это всё C++. С помощью его шаблончиков можно сваять сравнительно небольшой исходник, который будет компилироваться несколько минут и отхватит несколько гигов памяти. Тут никакой "-j4" не поможет.
Свопить на оптан?
Оптан стоит денег, медленнее сам по себе, кэш промахи при -jX стремятся к 100%.
По сравнению с терабайтом RAM, это хоть как-то вариант.
> По сравнению с терабайтом RAM, это хоть как-то вариант.И где тот оптан на терабайт?
Тут? https://www.amazon.com/Intel-Optane-905P-960GB-XPoint/dp/B07...
В россии, конечно, подороже https://www.citilink.ru/catalog/computers_and_notebooks/hdd/.../Но все равно в 8 раз дешевле оперативки.
> Тут?Ага, спасибо. Тогда у меня следующий вопрос: сколько ангелов уместится на булавочной головке?
Ога. Но при этом один уберфайл скомпилится гораздо быстрее, чем куча мелких ))) потому что как раз заголовки, шаблоны и т.п. только 1 раз обрабатываются.Это очень забавно, я всё думаю, почему до сих пор не сделали компилятор, который всё лепил бы в один файл, а потом бы его собирал.
Как не сделали? Сделали! и без компилятора даже: https://github.com/sakra/cotire
> Но при этом один уберфайл скомпилится гораздо быстрее, чем куча мелких )))100 КБ файл с шаблончиками -> 1 ГБ ОЗУ
10 МБ уберфайл -> 100 ГБ ОЗУ
Не, не выйдет.> почему до сих пор не сделали компилятор, который всё лепил бы в один файл
Тут и специфический компилятор не нужен. При сборке Chromium есть опция JUMBO build. Эффект, вроде, как раз тот.
Не сможешь делать инкрементальную сборку, т.е. даже при незначительном изменении будет нужно пересобирать всё. Есть костыли типа precompiled headers и может быть после появления модулей плюсы научатся делать нормальные промежуточные сборки модулей.
Ничего удивительного, шаблоны могут в рекурсии.
> С помощью его шаблончиков можно сваять сравнительно небольшой исходник, который будет компилироваться несколько минут и отхватит несколько гигов памяти.Пример шаблона ф студию. У меня всего 4Gb, компилирую проекты на 20Gb спокойно.
Например, установите (или скомпилируйте сами) библиотеку https://github.com/ukoethe/vigra и соберите крошечный набор enblend-enfuse https://sourceforge.net/projects/enblend/files/enblend-enfus...
Что при компиляции enblend, что enfuse в составе этого проекта наблюдаются задержки и рост потребления памяти.
Надеюсь, это не включат по умолчанию. Бывают проекты на нескольких языках, мне нафиг не упёрлось собирать их в 146 потоков.
Если ко времени выпуска впрод этот gcc м симтемой сборки будет крутится на односокетном 128-ми ядерном epyc 7003, то why not?
упрётся в память, компиляция плохо кэшируется
Главное в этой инициативе - чтобы компилятор был NUMA-aware. Т.е. не начал параллелить одну компиляцию на разные физические процессоры или модули, а только на ядра, имеющие общий блок памяти. Иначе будет замедление.
Главное они из существующего компилятора сделают такое УГ что единственным способом решения его проблем станет переход на раст.
А Rust, кроме своих, ещё начится компилировать исходники C, C++, Go, Fortran.
...а ещё лет через сорок до растоманов дойдёт, что их УГ можно было собирать параллельно...
Это ты к чему? Раст собирает параллельно столько, сколько я с ним вожусь, то есть с 2014 года как минимум.
> ...а ещё лет через сорок до растоманов дойдёт, что их УГ можно
> было собирать параллельно...Он и собирает параллельно. При сборке firefox сначала порождается процессов сколько надо, потом из них 1-2 начинают собирать rust и кол-во потоков утраивается. Как этот новый транслятор выйдет, так С его догонит по кол-ву лишних потоков.
Главное - чтобы оно выключалось. А лучше - чтобы не попало в gcc вообще. Уж что-что, а компиляция в разных процессах работает отлично, и при этом хорошо контролируется при нужде - хоть по нагрузке, хоть по памяти, хоть как.
GCC в прошлом. Модные парни уже давно перешли на MUSL + LLVM + CLANG
Ничего против clang не имею.
Но вот его баг в актуальной версии 8.0 с двойным вызовом деструктивных при исключении в лямбде реально достаёт. Баг есть, а фиксить не спешат.
s/деструктивных/деструкторов/
> GCC в прошлом. Модные парни уже давно перешли на MUSL + LLVM
> + CLANGДавно systemd собирается с MUSL?
не позорься со своим системд. Такие вещи даже страшно вслух произносить.
нормисы юзают S6/runint
> не позорься со своим системд. Такие вещи даже страшно вслух произносить.Экий ты шустрик в переобувке. Я позорюсь с твоим "Модные парни".
> нормисы юзают S6/runint
Дело не в переобувки. А в сути - почему люди добровольно отказываются от Поеттеринга во всех его проявлениях, будь то pulseaudio, systemd и еще что-нибудь.
> Дело не в переобувки. А в сути - почему люди добровольно отказываются
> от Поеттеринга во всех его проявлениях, будь то pulseaudio, systemd и
> еще что-нибудь.А в чём дело? Теперь ты меня спрашиваешь, почему MUSL не поддерживается в systemd. Мне то откуда знать, почему ты заявил что модный парень Поеттеринг перешёл на MUSL, когда это не так.
> будь то pulseaudioПоттеринг его забросил, и как только это случилось он стал конфеткой. Сейчас он что-то новое там хочет пилить, замена пульсе.
Конечно если речь не о прод серверах. там до сих пор на убунте 16.04 сидят или кастрированной Centos.
У кого-то прод серверы на венде и им норм.
Кому и кобыла невеста.
> не позорься со своим системд.Реклама uselessd?
> Такие вещи даже страшно вслух произносить.
Действительно. Шёл 2019 год, а ненужнод не может в Musl.
> Реклама uselessd?Но оно же умерло вскоре после рождения, еще лет 5 назад.
Как запилить тулчейн musl+clang и кросскомпилить под i586? Так и не нашел гайдов, под такой же кейс, но с gcc, гайдов куча. Может поможет кто-нибудь?
Простой 32-битный чрут не выручит часом?
>MUSL + LLVM + CLANGМодно, стильно, молодёжно!
А почему нет новостей как Столман отжигает в своем репертуаре?
Потому что ты эту новость не написал.
Подсказка https://www.opennet.ru/announce_news.shtml
Он уже _ИЗВИНИЛСЯ_ перед сжв https://stallman.org/archives/2019-jul-oct.html#14_September...)
А может быть, Столман это поддержит?
Дядя типереча тормознутые исходники на C++ будут быстро компилится?
Из серии "Давно пора"
В итоге оптимальным вариантом будет что-то вроде сочитания gcc -j N и make -j M -l K, да?..
Идеальным вариантом по-прежнему будет make -j N просто хотя бы из-за большого кол-ва исходников в проектах. Распараллеливать gcc имеет смысл только если пересобирать небольшую часть проекта во время разработки.
> Распараллеливать gcc имеет смысл только если пересобирать небольшую часть проекта во время разработки.То есть в большинстве случаев использования компилятора.
Кстати, а вот make-овый jobserver как раз может скумекать, когда собирает _одну_ цель -- и научиться добавлять компилятору уже _его_ -j или что там... тогда проблему неуправляемого параллелизма в квадрате вроде как получается решить.Ну или пущать с -jJ/N, условно говоря, где J -- сколько потоков разрешили самому make, N -- количество собираемых сейчас целей; но тут есть "уязвимость" к случаю, когда цели собираются с сильным разлётом длительности и предположение об N (кроме N == 1) перекашивает на протяжении заметной части общего времени сборки.
make чаще собирает одну цель когда линкует, а не компилирует. Проблема решается засовыванием всех процессов в cgroup-у. Т.е. make со всеми дочерними процессами должет отжирать примрно одинаковое кол-во CPU независимо от кол-ва процессов. Или можно костылить завышением nice всем процессам сборки. Опция -j N у компилятора может быть полезной, но ставить её лучше в фиксированное небольшое значение типа 2-3.
> Проблема решается засовыванием всех процессов в cgroup-у."новый стандарт" - ненужен.
Т.е., забив четыре потока, компиляция ускорится всего в полтора раза?Почему не приведено сравнение с вариантом, когда в четыре потока запускаются разные процессы, и какой выигрыш/проигрыш в этом случае по сравнению с новыми разработками.
я когда генту впервые пилил ставил -j30 и норм работает
надеюсь не на hdd? а то сложно предстаить какой там треск стоял:)
На HDD. Никакой не стоял. Средний объём исходника и какой это объём данных и IOPS в 30 потоков посчитать несложно, чтобы чуши больше не писать.
и в мейк файл MAKEOPTS=-j256
Надеюсь в апстрим не примут. Всё замечательно параллелится мейком, усложнение кода не оправдано.
Берешь 16 ядерный проц и ssd диск ставишь make -j16 и все быстро , а если у тебя проц 2 ядерный то выставить ты можешь только make -j2 или же хоть make -j32 все равно будет работать как j2 потому что проц двух ядерный , а не ишь че захотел 32 ядерный 32 потока. Но это ладно мне вот интересно что компилятор все время проц требует чем много процессорнее тем лучше , а где хоть один созданный компилятор который будет требовать скорость диска и чем больше скорость ssd тем быстрее было ехало , т.е я примерно докину свою мысль если бы я знал как программить компилятор то я бы драйвер процессорности заменил на драйвер диска.
Рекомендуется -j(n+1)
Так то да. Можно рискуть еще активизировать funroll-loops 03, а лучше выставить все возможные опти флаги
На Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz (4 ядра & даблтред) gcc 9.2 в полном комплекте собирается полчаса в 16 потоков make (make -j 16) при неполной загрузке дисковой подсистемы.