Планета Calculate

Облако тэгов

звуковые карты wi-fi udev news полезное работа mail swap abi_x86_32 KDE5 xsel серые листы winbind tracker ДНК cld cp1251 live-flash valve syslog QupZilla kvm cairo-dock автологин настройка цветов принтера freerdp mpg123 форматирование текста профиль пользователя bonding book dwm NetworkManager apvlv CLDG qemu rtorrent uptime rutorrent ati autologin ccze asus n10j press радио mailman BINHOST builder persistence icons bash CSS клавиатура kde5 cldg strategy benchmark форум lm_sensors screenshot alpha пресса feh tun slim maillist lighttpd шаблоны домашний сервер Gnome3 hdmi CSC remoteapp zswap networking flashplayer atom n270 Книги foto тема pam power KDE dhcpcd android textile bond Tor elogv многопоточная закачка asus x86 revision tint browser ati-drivers asterisk lirc vaio games desktop ups ускорение Xorg windows MultiTail BugTracker cpu family mplayer реестр PowerTOP su ПО RT mencoder package unmasking установка net cl-builder vulnerability blog tint2 программист LXC qrencode сайт утилитки на Icon EFI ControlMaster помощь день рождение LXD рассылка man LTE фидонет pre qupzilla db Calculate E17 wiki umd persistence-mode mirrorselect aufs xfce оптимизация AMD bootchart cryptsetup pxe birthday obmenu доступ rdp emerge radeon pf-kernel udisks ntfs-3g xen grub openbox midori кодировка CP1251 настройка цветов сканера beta keyboard systemd-udevd Calculate package sound gcc handbook ini.env grc MATE kernel pwkl cds командная строка firefox mate make.conf XZ kernek win7 acl jabber recordmydesktop windows 7 tweaks autounmask ext4 minicom двойная загрузка #calculatelinux linux tbn bug виртуализация benchmarking raid Firefox hibernate calculate2 w2k3 маршрутизатор gnome vpn support calculate-install-gui calculate utilities glx-dock CLC 4G calculate utils otter features profile Windows 7 Huawei new tools CDS dns dhcp настройка цветов фотоаппарата Calculate Linux Enlightenment сглаживание udisks-glue reader цветовой профиль icc фидо перенесено костыли распространение pdf cmc dropbox kde xfce pastebin twitter ssh шрифт authentication cls канал wget uksm LVM world мышка день программиста Midnight Commander sudo kde nano calculate-sources templates temperature pitivi calculate 2.2 portage CMC xchat ПДУ howto muqss theme звук dvcs meta djvu cl-update-profile X linuxdcpp 1C postgresql apache fontconfig lcdfilter fonts шрифты DPI atheros9285 ratigan монитор экран разрешение sony smplayer описание tuxonice flags optimization fonts bluetooth uefi VirtualBox nm-applet weechat 11.6 backdor qr-code alsa torrent tail forum интервью Audio utilities donation сеты monitoring распространение программ systemd Office security загрузчик dhcp binhost Скоростной алгоритм сжатия LZ4 TV GSC canto браузер CL14 xxkb участие USE samba screensaver MyRuLib lto distro xbmc keyexec python3 Снобизм stage luks pae UTF-8 оптимизация linux lautre дизайн energy saving plan репозиторий Summer Camp 3G курсор мыши install Calculate Utilities Библиотека shorewall gnome3 GPT steam производительность gentoo vlc p2p mp3 Plasma plugn ldap screencast icon w2k8 mc lvm Compose установка Icon в Calculate nexus repo git team CLDC Atheros XFCE cldm сборка из исходников openssh pulseaudio pgo помощь проекту CLDM liveusb ppp0 tap mouse vim перемещаемые профили cl-kernel iptables mirror android kde mtp livecd Gnome cpp livedvd установка linux e4rat calculate3 начало update caffeine binary code dns calculate linux antivirus free documentation calculate-install dmidecode kde и многопоточный звук codelite euse CLSK rip grub2 интернет unclutter freshplayerplugin hdd most openrc container release Либрусек acoola новости SSD bsa font iphone dconf btrfs E17 nut настройка цветов монитора план RSS безопасность ebuild ядро gnome 2 github ncurses почта удаленная сеть qutim разработка xorg packages openldap udisks template calculate postfix ffmpeg ubuntu clementine глобальное меню загрузка CL17 CLSL EAPI 2 CLS обмен опытом E17 Calculate telegram chromium OpenRC Timeless overlay libvirt создание подсветки синтаксиса bittorrent АТС nouveau network calculate-utils developers вакансия ParaType facebook locale Desktop eudev DNA irc оптимизация ядра CDS настройка linux atheros calculate linux obconf automagic pptp MidnightCommander cl-console-bg cl CLDX linux CLDL internet history objecticon видео blueman firewall layout Zen softraid CLD подсветка синтаксиса video python dmix debian localepurge google talk-plugin smart блог bash-completion кеширование proxy Icon Calculate USB Creator Calculate Linux Spamassassin брелок programming сервер Cinnamon unicode

Сборка Gentoo с LTO

Добавил(а) Николай Ка около 1 года назад

Как утверждают разработчики компилятора, в GCC 5 стало всё хорошо с LTO. Учитывая, что по не зависящим от меня причинам я давно систему не обновлял, я решил проверить это утверждение на практике и пересобрать мир посредством GCC 5.4 с мультитредом, LTO и gold линкером. Прошлые мои эксперименты с LTO на GCC 4.7 были признаны неудовлетворительными: большое количество пакетов не собирались, а из тех, которые формально собрались, какая-то часть (непонятно какая) собиралась по факту без lto благодаря дефолтному fat-objects, который позволял в случае неудачи тихонечко собрать пакет с кодом, сгенерённым на этапе компиляции безо всякого lto. На графит я решил не заморачиваться: выигрыш сомнительный, а стабильность сильно под вопросом.

Дисклеймер: автор не несёт ответственности за сломанную вами систему при попытке следовать этому руководству. Я попытался сделать его максимально подробным, но это всего лишь примерное описание шагов, который не заменит понимания того, как работает система и что надо делать. Без этого понимания невозможно будет решить возникшие проблемы -- а они будут! Используйте это как опорный конспект -- на свой страх и риск.

Итак,
1. Собираем GCC 5.4 из нестабильной ветки,

root # echo "sys-devel/gcc" >> /etc/portage/package.accept_keywords
root # emerge -u sys-devel/gcc
root # gcc-config -l

[1] x86_64-pc-linux-gnu-4.9.4 *
[2] x86_64-pc-linux-gnu-5.4.0

2. Переключаем компилятор командой

root # gcc-config 2 

3. Пересобираем libtools и устанавливаем binutils посвежее (9999 не обязательно, достаточно размаскировать нестабильную версию)

root # env-update && source /etc/profile
root # emerge --oneshot libtool
root # echo "sys-devel/binutils" >> /etc/portage/package.accept_keywords
root # emerge --oneshot binutils

4. Переключаем линковщик

root # binutils-config --linker ld.gold

Чтобы подхватывались нужные ar nm и ranlib, необходимо создать симлинк

root # ln -s /usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/liblto_plugin.so.0.0.0 /usr/x86_64-pc-linux-gnu/binutils-bin/lib/bfd-plugins

Некоторые устаревшие руководства предлагают поместить в make.conf "обёртки" для этих программ, на настоящий момент этого делать не нужно, достаточно прописать симлинк.

Далее руководство по gcc советует

5. обновить зависимые пакеты

root # revdep-rebuild --library 'libstdc\+\+.so.6' -- --exclude gcc

(подробности тут и тут)

В моём случае, учитывая, что я изменил режим компиляции и накопил большое количество обновлений, я попросту пересобрал мир. Мои флаги под AMD Athlon(tm) X4 760K:

CFLAGS="-march=native -pipe -Wno-all -O3 -flto=4 -fuse-ld=gold -mprefer-avx128 -mvzeroupper" 
CXXFLAGS="${CFLAGS}" 
LDFLAGS="-Wl,-O3,--sort-common,--hash-style=gnu,--as-needed -fuse-linker-plugin -s ${CGLAGS}"

Дальше процесс таков:

6. Создаём в директории /etc/portage/env файл с названием no-lto.conf следующего содержания:

CFLAGS="${CFLAGS} -fno-lto -fno-use-linker-plugin" 
CXXFLAGS="${CXXFLAGS} -fno-lto -fno-use-linker-plugin" 
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"

Кроме него, нам понадобятся файлы no-lto-bfd.conf

CFLAGS="${CFLAGS} -fno-lto -fno-use-linker-plugin -fuse-ld=bfd" 
CXXFLAGS="${CXXFLAGS} -fno-lto -fno-use-linker-plugin -fuse-ld=bfd" 
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"

vanilla-O3.conf

CFLAGS="-march=native -O3 -pipe -Wno-all" 
CXXFLAGS="${CFLAGS}" 
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"

gold.conf

EXTRA_ECONF="--enable-gold=default"

Создаём файл /etc/portage/package.env следующего содержания:

sys-devel/binutils gold.conf

нужный для того, чтобы при пересборке binutils не съехал линковщик. Далее настало время

7. собрать мир

emerge -e world

Если какой-то пакет не собирается, emerge вылетит с ошибкой. Смотрим, какой файл не собрался, и добавляем строку в наш package.env

<категория/пакет> no-lto.conf

У меня получился следующий файл

sys-libs/zlib no-lto.conf
dev-lang/perl no-lto.conf
x11-base/xorg-server no-lto.conf
sys-libs/ncurses no-lto.conf
sys-devel/gettext no-lto.conf
dev-qt/qtscript no-lto.conf
dev-lang/spidermonkey no-lto.conf
media-libs/x264 no-lto.conf
dev-python/notify-python no-lto.conf
app-text/rarian no-lto.conf
x11-libs/wxGTK:2.8 no-lto.conf
media-video/mediainfo no-lto.conf
media-libs/alsa-lib no-lto.conf
app-emulation/qemu no-lto.conf

Состав этого файла зависит от архитектуры, версии компилятора и пакетов и от состава установленных пакетов и приводится в качестве примера.

8. Особые случаи. В большинстве случаев предложенный подход сработает, но не всегда. Есть пакеты, которые собираются только с минимальным набором флагов, в моём случае это

dev-lang/python vanilla-O3.conf
sys-boot/grub vanilla-O3.conf

Есть пакеты, которые собираются, но не работают, у меня это

#сегфолтится с lto
media-sound/timidity++ no-lto.conf 

Есть пакеты, которые не собираются с gold-линковщиком

# требуют bfd
app-text/tesseract no-lto-bfd.conf 
app-i18n/poedit no-lto-bfd.conf
media-gfx/enblend no-lto-bfd.conf
sys-apps/gsmartcontrol no-lto-bfd.conf
media-gfx/rawtherapee no-lto-bfd.conf

Надо отметить, что при чтении elog файлов видно, что некоторые пакеты переключают линковщик сами и не требуют специальных манипуляций. Спасибо мейнтейнерам!

И наконец, самая хитрая категория: библиотеки, которые прекрасно собираются, но при оптимизации из них вычищаются нужные символы (объявленные локально?), из-за чего не собираются другие пакеты (у меня это poedit qemu rawtherapy gsmartcontrol и inkscape. Последний при этом даже собирается с lto, если библиотеки собраны без).

#В этих библиотеках иначе не видны все символы
dev-cpp/gtkmm no-lto.conf
dev-cpp/glibmm no-lto.conf
dev-cpp/atkmm no-lto.conf
dev-cpp/cairomm no-lto.conf
dev-libs/libaio no-lto.conf

Это полный список проблемных пакетов в системе, содержащей порядка 1100 пакетов. На настоящий момент система работает быстро и стабильно, хотя со временем могут выплыть ещё какие-то неожиданности. Так что, если кому-то будет нечего делать на праздники....


Комментарии

Comment

Добавил(а) Виталий Хомич около 1 года назад

В интернете немного написано про LTО оптимизации. Кому они полезны? Пользователям у которых система разбита на множество модулей? Чем-то данные оптимизации полезны тем кто собирают монолит под конкретную систему?

Comment

Добавил(а) Николай Ка 12 месяца назад

Это не "монолит", это всего лишь оптимизация кода, отложенная до момента, когда для этого доступно максимум информации. Количество модулей при этом не меняется.
ЛТО полезен всем. Сегодня в линуксе по умолчанию компилятор проводит оптимизацию кода помодульно. Это значит, что он, например, не может выкинуть функцию, которую никто никогда не вызывает, потому что она может вызываться из другого модуля и он об этом не знает. На этапе связывания у него есть вся информация и он может проводить более глубокие оптимизации: выкидывать неиспользуемый код, инлайнить функции из других модулей и т.д. При этом код (теоретически) получается более быстрым и меньшим по размеру. Средний выигрыш порядка 10%, что в масштабе системы уже заметно. Под оффтопиком уже давно компиляторы так работают, ну да там и деньги на разработку другие совсем.
Хотя возможны варианты: например, когда много инлайнов, код может даже распухнуть, но будет очень быстрым, или наоборот -- получится чуть медленнее, но сильно меньше. Статистика есть по ссылке в статье. ЛТО хорошо сочетается с -О3, которая генерит пухлый код, который в свою очередь глубже оптимизируется на этапе связывания.
Больше информации тут.

Comment

Добавил(а) Станислав Калиев 7 месяца назад

Добрый день!
Спасибо за статью, это первый детальный мануал по которому получилось собрать систему с LTO в кои то веки ))

Единственное как ни пытался но не могу перекомпилить sys-firmware/ipxe (который нужен qemu), валится с этой ошибкой:
make: *** [arch/x86/Makefile.pcbios:116: bin/usbdisk.bin] Ошибка сегментирования

Не сталкивались с такой бедой?

Comment

Добавил(а) Николай Ка 7 месяца назад

Добрый!

У меня и qemu и ipxe стоят, ничего не валилось.
Попробуйте внести пакет в список исключений.
Вообще, судя по приведённой вами строке, это make сам валится, попробуйте его пересобрать/обновить.

Comment

Добавил(а) Фёдор Ратиев 5 месяца назад

Привет!
Запилил 2 патча для dev-qt/qtscript-4.8.7 и dev-qt/qtwebkit-4.8.7 чтоб без ошибок с LTO собирались.

/etc/portage/patches/dev-qt/qtscript-4.8.7/qtscript-4.8.7_gcc-flto-fix.patch:

diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
index ef77e19..ef3340a 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
@@ -1176,7 +1176,7 @@ __asm void cti_op_debug_return(STUB_ARGS_DECLARATION)
 }

 extern "C" EncodedJSValue JITStubThunked_vm_throw(STUB_ARGS_DECLARATION);
-__asm EncodedJSValue cti_vm_throw(STUB_ARGS_DECLARATION)
+__asm EncodedJSValue cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM
 {
     ARM
     IMPORT JITStubThunked_vm_throw
diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
index da80133..10e678c 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
@@ -316,7 +316,7 @@ extern "C" {
     EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION);
-    EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM;
     EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION);
     JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION);
     JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
index 605a0ed..a7bd5dd 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
@@ -1088,6 +1088,14 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #define WARN_UNUSED_RETURN
 #endif

+#ifndef REFERENCED_FROM_ASM
+#if COMPILER(GCC)
+#define REFERENCED_FROM_ASM __attribute__((used))
+#else
+#define REFERENCED_FROM_ASM
+#endif
+#endif
+
 #if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK)))
 #define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
 #endif


/etc/portage/patches/dev-qt/qtwebkit-4.8.7/qtwebkit-4.8.7_gcc-flto-fix.patch:
diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
index 783586d..7943311 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
@@ -1264,7 +1264,7 @@ __asm void cti_op_debug(STUB_ARGS_DECLARATION)
 }

 extern "C" void* JITStubThunked_vm_throw(STUB_ARGS_DECLARATION);
-__asm void* cti_vm_throw(STUB_ARGS_DECLARATION)
+__asm void* cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM
 {
     PRESERVE8
     IMPORT JITStubThunked_vm_throw
diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITStubs.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITStubs.h
index 624b6be..a7399f5 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITStubs.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITStubs.h
@@ -430,7 +430,7 @@ extern "C" {
     void* JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION);
     void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION);
     void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION);
-    void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM;
 } // extern "C" 

 } // namespace JSC
diff --git a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h
index e8b03be..d0d3419 100644
--- a/qt-everywhere-opensource-src-4.8.7-orig/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h
+++ b/qt-everywhere-opensource-src-4.8.7/src/3rdparty/webkit/Source/JavaScriptCore/wtf/Platform.h
@@ -1181,6 +1181,14 @@
 #define WARN_UNUSED_RETURN
 #endif

+#ifndef REFERENCED_FROM_ASM
+#if COMPILER(GCC)
+#define REFERENCED_FROM_ASM __attribute__((used))
+#else
+#define REFERENCED_FROM_ASM
+#endif
+#endif
+
 #if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK)))
 #define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
 #endif

Спасибо!