Linux для всех

индекс
247,21

Использование альтернативных компиляторов в Gentoo на примере Intel Compiler Suite

В этой статья я хочу рассказать, как в Gentoo и других portage-based дистрибутивах для сборки пакетов исползовать отличный от gcc компилятор.
Выбор альтернативных компиляторов обширен: Intel Compiler Suite, Sun Studio Express Compilers, TenDRA C/C++ Compiler, Tiny C Compiler и прочие легковесные компиляторы.
Я рассмотрю переход на самый популярный (AFAIK) из альтернативных компиляторов — icc.
Вы можете спросить: а зачем это вообще надо? Дело в том, что icc оптимизирует код для исполнения на интеловских процессорах лучше, чем gcc.
Сравните сами:
тестируемая программа bunzip2 linux-2.6.32.tar.bz2 bzip2 linux-2.6.32.tar oggenc -q5 testfile.wav lame -V4 testfile.wav
среднее время выполнения (gcc) 22.118 91.452 108.554 98.438
среднее время выполнения (icc) 20.373 68.284 88.581 84.626
прирост скорости 8.5% 33.9% 22.5% 16.3%

Согласитесь, весьма неплохие результаты.
Конфигурация компьютера, на котором производилась проверка: Intel Core 2 Duo T7250 @ 2.00 GHz; linux 2.6.31-gentoo-r7 x86; gcc-4.4.2; icc-11.1.056; все тесты выполнялись в tmpfs — разделе, дабы не грешить на скорость i/o.

Установка


Если вы готовы, приступим к установке.
# emerge icc
icc требует для своей работы лицензию, воспользуемся бесплатным некоммерческим вариантом, который можно получить здесь. Когда вы получите .lic-файлик, положите его в /opt/intel/licenses.

Настройка portage


Сразу предупрежу, что некоторые приложения не собираются icc, а некоторые собираются, но не работают, хотя разработчики icc стремятся сделать его максимально совместимым с gcc. Поэтому нельзя сказать, что смена компилятора будет полной — что-то можно собрать только gcc, и отказываться от него мы не будем. У нас два варианта: компилировать всё icc, а отдельные приложения — gcc, либо наоборот, оставить основным компилятором gcc, а icc собирать только некоторые программы. Вам решать, какой из них выбрать — если вы не можете себе позволить долго ковыряться в системе, или просто не хотите лишних проблем, то для вас, скорее всего, более приемлим второй вариант; если же у вас достаточно свободного времени и/или желания попробовать что-то новенькое, то ваш вариант — первый.

Первый вариант: основной компилятор — icc, дополнительный — gcc


Будем считать, что флаги для icc в make.conf определены как ICCCFLAGS и ICCCXXFLAGS (как CFLAGS и CXXFLAGS для gcc); список пакетов, которые нужно собирать gcc, лежит в /etc/portage/package.gcc; особые флаги для отдельных пакетов — в /etc/portage/package.gcc-cflags и /etc/portage/package.icc-cflags.
Текущий компилятор определен в переменных окружения OCC и OCXX — вот и изменим их.
Для этого создадим скрипт /etc/portage/bashrc следующего содержания:

export GCC=${OCC} # сохраним старое значение переменных
export GCXX=${OCXX}
export OCC="icc" # меняем компилятор
export OCXX="icpc"
export GCCCFLAGS=${CFLAGS} # сохраним старые флаги
export GCCCXXFLAGS=${CXXFLAGS}
export CFLAGS=${ICCCFLAGS} # меняем флаги
export CXXFLAGS=${ICCCXXFLAGS}

[ -r ${ROOT}/etc/portage/package.gcc ] || return 0
while read -a target; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then # если текущий пакет указан в /etc/portage/package.gcc, то
export OCC="${GCC}" # возвращаем старый компилятор
export OCXX="${GCXX}"
export CFLAGS="${GCCCFLAGS}" # и флаги для него
export CXXFLAGS="${GCCCXXFLAGS}"
if [ -r ${ROOT}/etc/portage/package.gcc-cflags ]; then # а если еще и в /etc/portage/package.gcc-cflags, то
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags" # добавим еще флаги
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.gcc-cflags
fi
return 0
fi
done < ${ROOT}/etc/portage/package.gcc

if [ -r ${ROOT}/etc/portage/package.icc-cflags ]; then # аналогично для icc
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags"
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.icc-cflags
fi

export CC_FOR_BUILD="${OCC}" # маленький workaround

unset GCC
unset GCXX
unset GCCCFLAGS
unset GCCCXXFLAGS


Второй вариант: основной компилятор — gcc, дополнительный — icc

Аналогично предыдущему случаю, только тут список пакетов, собираемых icc, в /etc/portage/package.icc

[ -r ${ROOT}/etc/portage/package.icc ] || return 0
while read -a target; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then # если текущий пакет указан в /etc/portage/package.icc, то
export OCC="icc" # меняем компилятор
export OCXX="icpc"
export CFLAGS="${ICCCFLAGS}" # и флаги для него
export CXXFLAGS="${ICCCXXFLAGS}"
if [ -r ${ROOT}/etc/portage/package.icc-cflags ]; then # а если еще и в /etc/portage/package.icc-cflags, то
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags" # добавим еще флаги
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.icc-cflags
fi
export CC_FOR_BUILD="${OCC}" # маленький workaround
return 0
fi
done < ${ROOT}/etc/portage/package.icc

if [ -r ${ROOT}/etc/portage/package.gcc-cflags ]; then # аналогично для gcc
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags"
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.gcc-cflags
fi
fi


Все! Ваша система готова собирать пакеты новым компилятором.

Плюсы и минусы



Плюс

Один, но жирный. Заметное ускорение работы процессороемких процессов — (де)кодирования аудио/видео, (де)шифрования, etc.

Минусы

1. Неполная совместимость с gcc. Некоторые программы не собираются icc, некоторые собираются, но не работают. Например, программы, использующие алгоритм LZMA (xz-utils, p7zip), собираются, но не распаковывают архивы — мол, они битые. Уверен, что это не единственный пример.
2. icc линкует исполняемые файлы с собственными библиотеками, и, если вы по каким-либо причинам решите удалить его, то вам придется пересобирать все пакеты, собранные им.
3. icc закрыт. Для некоторых это не минус, но согласитесь, что открытие его исходников никому бы (кроме Intel, конечно) вреда не принесло.

Заключение


Хочу сказать, что переход на другие компиляторы ничем не отличается по сути — в скрипте нужно всего лишь изменить icc на выбранный компилятор.

Надеюсь, что эта статья будет вам полезна.

P.S. Спасибо gribozavr за инвайт!
+97
6 февраля 2010, 23:09
31

комментарии (53)

+26
silentroach #
Внезапно люди на хабре новичку за неплохую статью уже насрали в карму из-за встретившегося слова Gentoo? Тьфу, бля, даже противно. Автор, не обращай внимания на таких мудаков и пиши дальше, статья отличная, спасибо.
0
Rafael_Delon #
И мне статья понравилась.
–9
Andrey_Rogovsky #
Статья — тупой копипаст с вики и причем неполный
0
tiandrey #
Вы не правы. Да, я читал вики до этого (иначе бы не было и этой статьи), однако статью писал, не используя никаких других ресурсов. Сейчас посмотрел — действительно, очень похоже на перевод, но это не так.
+2
chilly #
Скрипты один в один с вики en.gentoo-wiki.com/wiki/Intel_C%2B%2B_Compiler.
+1
tiandrey #
Читайте комменты ниже, на авторство скриптов я и не претендую
–1
ekzo #
убогий копипаст.
+2
DIDJER #
Да всё с вики, для того она и придумана. А автору спасибо потому, что я бы и не узнал не о каких альтернативных компиляторах и соответственно не стал бы копать в этом направлении. Тут его задача донести до читателей о такой возможности. Так как это хабр всё же, то необходимо писать не тупо — «Ребята есть альтернативный способ, вот ссылка». А рассказать о плюсах, минусах, что да как.
+1
ZogG #
ты еще скажи, что гента один в один как с сайта gentoo.org. понятно человек пишет статью, собирая информацию с интернета(газет/новостей)
0
moooV #
Я тоже на генту, буду пробовать!

Но один вопрос только — много ли встретилось не собравшихся пакетов при сборе системы (скажем, до уровня иксов + кде/гном)?
0
tiandrey #
Я не стал рисковать и пересобирать всю систему, ограничился аудио- и видео-кодерами и архиватором.
+1
tiandrey #
А вот Qt (4.6.1) им точно не собирается
0
chilly #
Надо не всю систему, а только выборочные пакеты, в вики есть небольшой список. Собрал gimp но он у меня файлы отказывался открывать. Ещё говорят можно python собрать, но я не рискнул, ибо вся система портежей на нём закручена.
+5
vosi #
не понимаю, за что недолюбливают генту, очень хороший, добротный дистр
–2
romx #
За ее пользователей ;-}
+7
tzlom #
хорошая gentoo статья, продолжай в таком духе

от себя добавлю что пользователям AMD процессоров на icc лучше не смотреть-прироста производительности не будет, даже наоборот
0
vasyathriller #
www.opennet.ru/opennews/art.shtml?num=24891
Тут есть над чем порассуждать. Впрочем, для укрощения ICC на AMD и вправду нужно извернуться так, что проще забить и заюзать GCC.
0
tzlom #
ну не скажите, патчи на ICC вроде есть даже где то в недрах генту-вики, это не сложно
а «использовать технологию виртуализации» это уже попахивает бредом :)
+1
Gorthauer87 #
Она вообще то из gentoo-wiki, вообще я с icc баловался, но овчинка выделки не стоит
+1
tiandrey #
Скрипт — да, из вики, немножко изменен. А статью сам писал
НЛО прилетело и опубликовало эту надпись здесь
0
tiandrey #
У меня в кроне стоит синк и обновление в три часа ночи. Итого я просыпаюсь, а софт уже свежий. Ну а если иногда что-то новое надо поставить — ну не больше часа-двух, если нечем больше заняться.
НЛО прилетело и опубликовало эту надпись здесь
+2
Gorthauer87 #
Я так дообновлялся %)
+2
silentroach #
зря думаете что gentoo — это сплошная компиляция ;)
0
dgeliko #
Gentoo — это не только свежий софт, но и 2-3 ценных диетическиих компилятора =))
+1
xiWera #
последний раз когда я его пробовал он (icc) страдал сильнейшим когнитивным диссонансом при виде c++
0
izard #
Конечно, ведь С++ компилятор Интел зовется icpc, а не icc. Это как gcc и g++.

А если серьезно — фронтенд действительно парсит C++ up to the spec, так как и пишется людьми из C++ commitee. Не знаю, плюс это или минус. Но проблемы бывают.
+1
xiWera #
тогда с с++ были сплошные проблемы, чуть более менее сложная зависимость между шаблонами, ицц становится слепым и беспомощным: «ничего не вижу, ничего не знаю, ваших параметров шаблона вывести не могу, не понимаю, не умею»
0
Constantin #
en.gentoo-wiki.com/wiki/Intel_C%2B%2B_Compiler Оф. мануал, цифры в таблице сравнения производительности заинтересовали, как-то не очень верится что разница настолько существенна
+1
Constantin #
В общем погуглил на тему производительности, есть даже проект www.linuxdna.com/ — свежие ядра оптимизиролванные для сборки icc.
В среднем разница, судя по отзывам, 8-9%, но сильно страдает стабильность, так что для себя пока не вижу смысла
0
kovyrlo #
Спасибо! Прирост скорости улыбнул, но, пожалуй, подожду, пока они допилят совместимость с gcc
+1
pawnhearts #
ещё есть sun compiler
+2
soomrack #
Без озвучки флагов (CFLAGS, CXXFLAGS) данные по приросту скорости, мягко говоря, не интересны.
0
tiandrey #
CFLAGS="-O2 -pipe -mtune=native -march=native -mmmx -mcx16 -msse -msse2 -mssse3"
CXXFLAGS="${CFLAGS}"
ICCCFLAGS="-O2 -xT -gcc"
ICCCXXFLAGS="${ICCCFLAGS}"
+1
soomrack #
> CFLAGS="-O2 -pipe -mtune=native -march=native -mmmx -mcx16 -msse -msse2 -mssse3"

-march=native должно само включать "-mtune=native -mmmx -mcx16 -msse -msse2 -mssse3"

Кроме того, учитывая надежность icc, корректней было бы сравнивать с -O3.
0
tiandrey #
Да еще бы и с graphite…
0
ZogG #
тока хотел спросить про флаги и про архитектуру (64 или 32). сам месяяца 3-4 назад перешел на 64(не было надобности, ибо почти не пользуюсь программами, которые требуют проц на полную) и как раз в новом гсс (тогда он был еще замаскирован) появился флаг native (с какой версии там кстати?). так прирост был большой, компиляция в несколько раз быстрее и кодирование видео в пару раз быстрее. так что надо таблицу с архитектурами и флагами разными.
0
u_story #
а вы не пробовали с флагами ковыряться?
Меня вот всегда мучала мысль, что если в gcc правильно понавтыкать флаги, то код получится ничуть не хуже чем у icc.
Например, тот же -03, -ftree-vectorize и т.д.
0
Gorthauer87 #
Было бы интереснее clang присобачить, он хотя бы свободный
0
LupineDreamer #
Ну что ж. Будем ковырять :)

Спасибо автору за статью.
0
B_Sadovskiy #
Спасибо! Было интересно читать.
+3
Vasily_Pupkin #
Я раньше использовал icc в генту, но отказался. Действие сопостовимо с наркотиком. Сначала все собирается, потом привязывается к либам icc. А потом, ВНЕЗАПНО, что-то не собирается. А gcc не собирает, потому что тоже что-то неподходит. И привет revdep-rebuild. А еще хуже, когда в новой версии цомпилятора выкидывают какую то либу, с которой все скомпилено было раньше. И получаются клещи. Воющем я отказался. Стабильность лучше
0
ainu #
Любопытно, прирост очевиден. А для Debian/CentOS есть пакеты (либо сами системы в виде сборок), перекомпилированные таким-же макаром с расчётом на Intel-процессоры?
0
tiandrey #
Не знаю, могу предложить собрать самостоятельно в чруте. Наверное, есть более более юзер-френдли способ
НЛО прилетело и опубликовало эту надпись здесь
+1
smind #
собираю миднайт комадер tcc-ой, по сравнению с gcc компилит быстрее раза в 2-3…
+1
mrded #
то что компилит быстро, это еще не показатель того что собранное приложение будет быстрее
0
smind #
мне не нужно чтобы быстро работало, мне нужно чтобы быстро компилило, разные задачи у нас. Я просто очень много и нудно пишу своего и тестирую чужого… собирать приходится много и нудно…
0
mrded #
а если GCC собрать с помощью ICC, он будет круче?:)
+1
tiandrey #
Ну вообще-то при сборке gcc bootstrap'ится, т. е. сначала собирается внешним компилятором, а потом сам себя пересобирает два раза, т. е. если на первом шаге что-то изменится, то на втором все изменения будут потеряны. И вообще icc не соберет gcc AFAIK
0
CyMpak #
Серьезная техническая статья на Хабре?! Хабр уже не торт…
НЛО прилетело и опубликовало эту надпись здесь

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