Как стать автором
Обновить

Комментарии 55

«LTO оптимизация» — это «Link Time Optimization оптимизация»?
Да. Вы наверное про масло масленое «optimization оптимизация»? Так было написано для лучшего понимания русскоговорящему человеку.
llvm.org/docs/LinkTimeOptimization.html
gcc.gnu.org/wiki/LinkTimeOptimization
Вы не поняли, а вот вас понял сразу. Был просто раскрыт термин LTO для понимания его смысла. Потому что на русском нормально написать LTO оптимизация. В тексте было просто раскрытие термина. Это было сделано в первую очередь для тех кто не знаком с терминологией. На самом деле очень долго подбирал слова, чтобы текст был понятен не профессионалам, и чтобы профессионалов не задеть. В том предложении поэтому остановился на таком варианте. Масло масленое заметил еще когда писал статью, но остановился на таком варианте написания.
«Оптимизации на этапе связывания»
Представьте себе, что у вас исходный код программы занимает несколько гигабайт, такой размер нередко встречается в серьезных программах
Например?
Оптимизированное дерево может быть преобразовано в машинный псевдокод понятный компилятору.
Скорее всего это не псевдокод, а байткод.

Статье не хватает бенчмарков. Так же непонятен вопрос обновления — запускается ли автоматическая пересборка или нет. Так же вопрос, почему выбран бинарный дистрибутив.
Например?

alsoijw
du -sh /tmp/linux-5.12.10/
1,2G /tmp/linux-5.12.10/


Скорее всего это не псевдокод, а байткод.

Да LLVM IR. LLVM использует свой язык описания для описания многих структур поэтому псевдокод не является ошибкой. Пример github.com/llvm/llvm-project/commit/5b149c437194d10877e9e45b3d8cc9252af1944b

Статье не хватает бенчмарков. Так же непонятен вопрос обновления — запускается ли автоматическая пересборка или нет.

perf в помощь. У меня лично загрузка процессора упала при вызове API ядра. Пересборка остальных программ где-то быстрее где-то медленнее. В общем дало выигрыш хороший, упала загрузка процессора, стало меньше потребление памяти, анимации стали плавнее и производительнее. Сложно оценивать производительно современных компиляторов, в одних программах код будет быстрее в других наоборот. У меня есть бенчмарки для себя, где-то GCC выигрывает почти в 2 раза в скорости, где-то clang оказывается в раза 2 быстрее. clang в первую очередь дает более прогнозируемый код и не ломает поведение. Мне известны случаи когда GCC ломал поведение программ в случае переоптимизации, и поэтому разработчики программ отключали некоторые типы оптимизаций. Как знаю, в случае с рекурсивными вызовами их производительность будет увеличена в LLVM 13, но рекурсия в принципе является плохим тоном программирования и лучше ее избегать, переписывать алгоритм где есть возможность.

Так же непонятен вопрос обновления — запускается ли автоматическая пересборка или нет.

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

Так же вопрос, почему выбран бинарный дистрибутив.

Мне не нужно собирать все. Дистрибутив выбран по принципу самое свежее ПО. Критические программы у меня собираются вручную. Arch Linux для этого хорошо создан и все делается удобно, можно автоматизировать сборку. У меня сборка всего критического автоматизирована, плюс где-то есть патчи которых нет в официальных пакетах github.com/h0tc0d3/arch-packages Плюс где-то программы даже свежее.
Пересборка остальных программ где-то быстрее где-то медленнее. В общем дало выигрыш хороший, упала загрузка процессора, стало меньше потребление памяти, анимации стали плавнее и производительнее.
Вот это хочется увидеть в конкретных цифрах.
Мне не нужно собирать все.
Существуют дистрибутивы с бинарным кешем, позволяющие пересобирать конкретные программы. В этом случае, пересборка будет происходить при обновлении системы автоматически, без костылей с кроном, там будет отдельный пользователь для сборки и так далее.
alsoijw вы можете про это написать статью, с радостью вас почитаем. Мною было написано про то чем пользуюсь сам и давно. Мне как разработчику clang больше нравится как компилятор так как он лучше ловит ошибки в коде и проблемы оптимизации. Переходить обратно на GCC ради бенчмарков мне просто лень. На clang перешли FreeBSD и MacOS и лично это только поддерживаю. Все проблемы медленного кода можно удобно отловить в clang, переписать код и улучшить производительность, тем самым просто убрать разрыв там где gcc быстрее, в gcc этого нет. Для меня в первую очередь производительность зависит от разработчика, а не от компилятора или языка программирования. Для себя предпочитаю полу автоматический режим, могу накатить патчи, протестировать что-то, быть уверенным, что не будет такого, что сборка сломает систему когда меня не будет рядом. Всегда могу быстро откатить систему назад.
Мне известны случаи когда GCC ломал поведение программ в случае переоптимизации, и поэтому разработчики программ отключали некоторые типы оптимизаций.

Вот, кстати, никогда не понимал такую практику / советы. Если оптимизация ломает программу, значит в коде есть ошибка и надо её исправить. Иначе она может точно также неожиданно проявиться потом из-за какой-нибудь другой оптимизации при обновлении компилятора, причём независимо от того GCC это или Clang, а может даже и без оптимизаций на каких-нибудь других входных данных.

Если оптимизация ломает программу, значит в коде есть ошибка и надо её исправить.

Вопрос в том в коде чего ошибка - в коде компилируемой программы или в коде компилятора.

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

Вы так говорите, как будто очевидно, в какой именно строке какая именно ошибка. А дальше уже вопрос ресурсов для поиска этой ошибки.
alsoijw человек просто перепутался в ошибках компилятора и ПО, ошибки компилятора посложнее ловить и ПО не всегда может их решить. Проблемы производительности ПО через профилировщик видно, в дальше можно просто посмотреть на ошибки оптимизации этого куска кода, компилятор при передаче определенных параметров может показывать такие ошибки, в clang это делать удобно. Ошибки компилятора это сложнее, чаще всего он предустановлен и даже если сделают быстро патчи, то не факт что они быстро появятся в дистрибутиве… Только на днях видел в каком-то пакете багрепорт связанный с GCC, и там отсылка на сам баг в GCC. У меня были тоже подобные баги с LLVM, но у меня git версия и патчи сразу переношу в свой пакет aur.archlinux.org/packages/llvm12-git
Вот к примеру баг llvm с которым лично столкнулся и там даже отписался bugs.llvm.org/show_bug.cgi?id=49915

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


Вот ограниченность ресурсов — очевидно корректный аргумент, но только если качеству продукта достаточно низкий приоритет отдаётся.

Aldrog вы в принципе мало понимаете в разработке компиляторов, столкнетесь с компиляторами ужаснетесь от багов))) Никогда не слышали про баги GCC c -funroll-loops? wiki.gentoo.org/wiki/GCC_optimization/ru Некоторые оптимизации дают сбой, их компилятор чаще всего отключает, отсюда может быть потеря производительности. Компилятор старается оценить сложность оптимизации, если во время оптимизации оказывается, что сложность оптимизации высокая, то он может отказаться от оптимизации или вовсе создать не корректный код. Начиная с gcc 9 включили агрессивное разворачивание циклов по умолчанию, и довольно много тогда было багрепортов, что ПО работает не везде корректно. Довольно сложно в компиляторах предусмотреть все возможные ошибки оптимизации. Тот же full lto в случае сложности оптимизации тупо генерирует много кода и код наоборот становится медленнее. Поведение всех компиляторов очень отличается. На мой вгляд в этом плане самый умный clang.

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


Впрочем, теперь я понял, что именно вы представляете как преимущество clang.
Не раз встречал на хабре мнение, что любые агрессивные оптимизации — это некорректная работа компилятора, поэтому долго не мог понять, что вы имеете в виду под "корректностью работы -O3" и "поломкой поведения программ".

У меня были тоже подобные баги с LLVM, но у меня git версия и патчи сразу переношу в свой пакет aur.archlinux.org/packages/llvm12-git

И как, принимали патчи? А то я в своё время отправил тривиальный патч, а потом выяснил, что данная проблема уже поднималась, и присылался гораздо более полный патч, однако его так и не приняли, просив доработать. А потом, после нескольких правок с ним, как и с моим всё заглохло.
В компиляторы у меня не было патчей. В других проектах принимали, и так же отклоняли по разным причинам. Все сильно зависит от мейнтейнера. Где-то замечательные программисты и с радостью идут на диалог, помогут и принимают патчи, где-то совсем наоборот. Не мало раз было, что присылал патч и говорили в следующем релизе этого куска кода не будет и уже алгоритм переписан.
А что с производительностью, какие-то бенчмарки выполнялисьс дефолтным и самосборным ядрами? Интересно, есть ли какое-то ускорение работы от перехода на clang.
VioletGiraffe комментарием выше есть уже ответ на ваш вопрос. Судя по perf у меня есть улучшение общей производительности. В общем система стала стабильнее, пропала дерготня, особенно в анимациях kde и в хромиум, рендеринг и загрузка вебстраниц происходят заметно быстрее.
Очень странно, что Ryzen 9 3900x + AMD Radeon 5700 XT не вытягивает базовую анимацию рабочего стола без дерготни. У меня такого даже на дохлом атоме не было в те времена, когда LLVM никто всерьёз не воспринимал.
yarston ничего странного. Кривая оптимизация может даже быть из-за неправильного разворачивания кода GCC. Плюс некоторые пакеты имеют плохую оптимизацию, а где-то вовсе криво собираются в Arch Linux. Поэтому мною были созданы свои сборочные файлы. До mesa 21 и ядра 5.10 моя видеокарта плохо поддерживалась, сейчас все стало лучше. До сих пор в ядре есть где AMD не совсем корректно работает, например управление электропитанием. Ядро под Intel лучше оптимизировано. Но вот что радует AMD нанимает разработчиков и с каждым месяцем ситуация меняется в лучшую сторону. Вообще графический стек это самое слабое место Linux, у меня к примеру в хромиум не работает hardware acceleration. Проблема уходит корнями далеко в прошлое, поэтому сейчас активно пытаются развивать wayland, но для меня он сырой еще, у меня с ним кучу багов, поэтому от него пришлось пока отказаться community.kde.org/Plasma/Wayland_Showstoppers
Очень странно, что Ryzen 9 3900x + AMD Radeon 5700 XT не вытягивает базовую анимацию рабочего стола без дерготни.
Скорее всего, это проблемы KDE и Xorg, хотя я натыкался и на проблемы с GNOME. Порой складывается впечатление, что разработчики этих сред сами их не используют, так как в других средах, например Mate данных проблем нет.
меня к примеру в хромиум не работает hardware acceleration
В чём проблема? Vaapi не включается? Что насчёт firefox?
В некоторых пакетах разработчики просто кладут на всех. Пишешь им багрепорты, а они забивают и даже не отписываются. Есть не мало адекватных, которые патчи быстро делают. Но так же не мало кто забивает на критические ошибки, мне даже самому не редко приходилось писать патчи потому что авторы забивали болт. В линукс есть такая штука, что старые разработчики боятся иноваций и всячески этому мешают, готовы поддерживать 30 летние компы, но отказываются от растущего рынка новых, например так было с автором zlib-ng когда его патчи не приняли в zlib, разработчики xorg не очень идут на помощь wayland и не спешат решать общие проблемы. Радует что mesa и ядро развиваются хорошо, привносят инновации и выкинули мертвые код для старых систем, чтобы открыть новым лучшую производительностью

Canvas: Hardware accelerated
Compositing: Hardware accelerated
Multiple Raster Threads: Enabled
Out-of-process Rasterization: Disabled
OpenGL: Enabled
Rasterization: Software only. Hardware acceleration disabled
Skia Renderer: Enabled
Video Decode: Software only. Hardware acceleration disabled
Vulkan: Disabled
WebGL: Hardware accelerated
WebGL2: Hardware accelerated
Я пересобирал ядро, так как хотел включить один флаг. Пересборка была довольно долгой, так что я решил отключить очевидные флаги. В результате незначительно, на несколько десятков мегабайт увеличился максимально доступный объём памяти.

По большей части Clang победил в бесполезных тестах на нейросети, которые редко на CPU считают.
В более-менее полезных задачах преимущество, в основном, у GCC, да и то незначительное.

Перечитайте статью с самого начала, и пройдитесь по результатам каждого теста, у вас немного не правильные выводы.
Про русскую букву Ж это конечно пять. Вы всерьёз думаете что собирать таким образом ядро пойдет человек который не знает vim и не может найти двоеточие на клавиатуре?
Почему нет? Собрать ядро с LTO нет ничего сложного. Насчет vi и vim первая сложность в обучении это как выйти из них и как перейти в режим ввода команд, дальше обучение очень простое. По этой причине многие не пользуются ими и не понимают их. Владение vi и vim никак не показатель опыта и не маркер владения Linux. Человек может всю жизнь пользоваться nano и знать Linux лучше вас. Статья в первую очередь для тех кто хочет обучиться большему.

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

Что-то мне кажется, что для таких опытов лучше подойдёт Gentoo.

Gorthauer87 без разницы, хоть многое у меня собирается вручную, большая часть это бинарные пакеты дистрибутива. У меня все собирается и обновляется за минимальное и вполне адекватное время, и без напряга. Подойдет в принципе любой дистрибутив, просто написал про тот с которым мне удобнее работать. Основная задача статьи открыть дополнительные горизонты для оптимизации, где их будут применять в принципе без разницы. Хоть в centos 7 и на сервере в продакшене, в принципе стабильности всех решений достаточно для серверов. Ядро с clang собираю давно и стабильность системы имхо выше, LTO тестирую с 5.12.6 и ничего не ломалось, стабильность хорошая. Часть пакетов в arch linux и так собирается с LTO и GCC, просто переписал сборочные файлы под lto thin и clang.
для таких опытов лучше подойдёт Gentoo.
а в генту сейчас можно поставить вообще всю остальную систему из бинарных пакетов за несколько минут (при наличии шустрого интернета)? Арч тем и хорош, что он бинарный — но свежий, и свои пакеты собирать легко. Поэтому можно экспериментировать с чем хочешь, а с чем не хочешь — ставить из репо готовое. Много-много лет назад я именно поэтому его и выбрал.

Это к форкам, например, Calculate. Или можно попробовать NixOS(это не форк, но имеет множество подходящих для данной задачи свойств).

Спасибо за хорошую и полезную статью!
За всё время знакомства с арчем не заходил дальше сборки git версий из AUR и пересборки в ABS. А после прочтения статьи — прямо захотелось повторить. Спасибо за статью!

И ни слова, собственно, о том, что эта самая LTO вообще делает. Что компилятор там может оптимизировать? Функции местами переставлять? Инлайнить функции?

Следующий подводный момент заключается в DKMS, после установки ядра собранного с помощью Clang, DKMS пытается собрать модули ядра с помощью GCC. По этой причине сборка и установка DKMS модулей в новое ядро завершается ошибкой.

Интересно, почему модули собранные GCC не работают с ядром, собранным clang. Ведь, по идее, между ними только заголовки ядра (при компиляции) и бинарный интерфейс (при загрузке). Падает, я так понимаю, именно загрузка, да? Получается clang укладывает структуры или делает вызовы по-другому? Или у него другой формат .ko-файлов?
event1 честно говоря не знаю. Cамая частая ошибка c llvm и lto, что o файлы содержат LLVM IR, а его могут обработать только тулчейны llvm. Эта ошибка бывает когда сборочные скрипты пытаются использовать другой ld, ranlib, ar. Уже не помню ошибку с DKMS, так как эта ошибка была еще давно до lto, видимо была тоже причина в этом.
да, но ведь тут clang собирает ядро, а его .o-файлы не нужны для DKMS. Ядро же не ожидает .ko-файлы с LLVM IR, правда? Это было бы очень удивительно.
Вот как ругается DKMS:
Building module:
cleaning build area…
KERNELDIR=/lib/modules/5.12.10-noname/build make driver...(bad exit status: 2)
Error! Bad return status for module build on kernel: 5.12.10-noname (x86_64)
Consult /var/lib/dkms/openrazer-driver/3.0.1/build/make.log for more information.

make.log
make -C /lib/modules/5.12.10-noname/build M=/var/lib/dkms/openrazer-driver/3.0.1/build/driver modules
make[1]: вход в каталог «/tmp/linux-5.12.10»
CC [M] /var/lib/dkms/openrazer-driver/3.0.1/build/driver/razerkbd_driver.o
gcc: ошибка: unrecognized command-line option «-Qunused-arguments»
gcc: ошибка: unrecognized command-line option «-mno-global-merge»
gcc: ошибка: unrecognized command-line option «-fsplit-lto-unit»
make[2]: *** [scripts/Makefile.build:271: /var/lib/dkms/openrazer-driver/3.0.1/build/driver/razerkbd_driver.o] Ошибка 1
make[1]: *** [Makefile:1851: /var/lib/dkms/openrazer-driver/3.0.1/build/driver] Ошибка 2
make[1]: выход из каталога «/tmp/linux-5.12.10»
make: *** [Makefile:25: driver] Ошибка 2

А-а-а. То есть он ядерные clang-овые аргументы пытается в gcc скормить. Интересно… Наверное можно DKMS научить использовать другие, не-ядерные, аргументы.
Скажите, а без vim ничего работать не будет, да?
Тогда какой смысл в пересказе руководства по vim, вместо того, чтобы просто описать, что должно быть в файлах? Или переменная дефолтного редактора ускользает от понимания?
А где вы там нашли пересказ руководства по vim? Вас это как-то задевает или vim не осилили? Или может у вас скролл на мышке сломался? В чем проблема? Если вам это не было полезно, не значит, что другим так же. Вам же не указываю как писать вам ваши статьи, откуда столько негатива к vim?
Ну это как в руководстве по переборке двигателя вдруг сделать отступление и начать рассказывать как работать с разводным ключом. Малость бессмысленно — если уж человека заинтересовала переборка двигателя, то с ключом, будь он ему нужен, он и сам разберется. А если он предпочитает накидной — то ему тем более эта информация как пятая нога.
Не похоже, так драматизируете будь-то скролл на мышке сломался…
Вам может не нравится, но вот знаете, книжки для чайников имеют очень высокий рейтинг продаваемости, а все потому, что там пишут и объясняют самые простые вещи. И самое главное мне отписалось в личку несколько людей, которые не работают с линуксом, но заинтересовалось им благодаря статье. Если не верите могу скинуть скрины переписки. Рейтинг одобрения у статьи 85,9% и 76,8% это говорит о многом. Так что можете дальше завидовать и плеваться ядом, не зная к чему еще придраться. Еще и карму минусуете. Позорище.
Ох, как бомбит. Ладно, явно диалог не имеет смысла.
Бомбит вас, и видимо очень сильно, что не ограничились одним комментарием и даже минусанули карму, а мною лишь констатируются факты.
Оказывается, можно в CFLAGS и CXXFLAGS добавить -flto=thin, и тогда автоматом всё будет собираться с тонкой оптимизацией. Возможно, ещё куда-то.
Можно, но я бы не рекомендовал это делать в makepkg.conf или .bashrc или .profile.
В моих сборочных скриптах он добавлен, но не везде, только где я смог заставить его работать, и где смог сделать патчи, переписать сборочные скрипты или где мне разработчики сделали патчи на мой запрос. Мои сборочные скрипты сильно отличаются от тех, что в официальном репо. И не мало пакетов просто так не собирается с -flto.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий