Техника оптимизации под линуха

       

Общие соображения по оптимизации


Качество оптимизирующих компиляторов обычно оценивают по результатом комплексных тестов (мультимедийных, "общесистемных" или математических). Что именно оптимизируется и как — остается неясным. Основной "интеллект" оптимизаторов сосредоточен в высокоуровневом препроцессоре — своеобразном "ликвидаторе" наиболее очевидных программистских ошибок. Чем качественнее исходный код, тем хуже он поддается оптимизации. Только ведь… над качественным кодом _работать_ надо! Много знать и ожесточенно думать, ломая карандаши или вгрызаясь в клавиатуру. Кому-то это в радость, а кто-то предпочитает писать кое-как. Все равно, мол, компилятор, соптимизирует!

Желание перебросить часть работы на транслятор — вполне естественно и нормально (для творчества больше времени останется), но нужно заранее знать, что именно он оптимизирует, а что только пытается. Но как это можно узнать? На фоне полнейшей терминологической неразберихи, когда одни и те же приемы оптимизации в каждом случае называются по-разному, прячась за ничего не говорящими штаммами типа "copy propagation" (размножение копий) или "redundancy elimination" (устранение избыточности), требуется очень качественная документация на компилятор, но она — увы — обычно ограничивается тупым перечислением оптимизирующих ключей с краткой пометкой за что каждый из них отвечает. Какие копии размножает компилятор и с какой целью? Какую избыточность он устраняет и зачем? Не является ли размножение внесением избыточности, которую самому же оптимизатору и приходится удалять?!

Взять хотя бы документацию на компилятор Intel C++ 7.0/8.0. Будь у меня бумажная версия, я бы ее "употребил". Все равно, ни на что другое она не пригодна. Это просто перечень ключей командной строки, разбавленный словесным мусором, в котором нет никакой конкретики. Скачайте для сравнения документацию на компилятор фирмы Hewlett-Packard (кстати, моя любимая фирма): http://docs.hp.com/en/B6056-96002/B6056-96002.pdf.
Доходчивое описание архитектуры процессора, советы по кодированию, тактика и стратегия оптимизирующей трансляции на конкретных примерах. Настоящая библия программиста!

Остальные компиляторы оптимизируют примерно таким же образом, поэтому, эта библия вполне приемлема и для них. "Эффективность оптимизации" из абстрактных цифр превращается серию простых тестов, каждый из которых можно прогнать через транслятор и потрогать руками. Дизассемблирование откомпилированных файлов позволяет однозначно установить — справился ли оптимизатор со своей задачей или нет.

Здесь сравниваются два наиболее популярных Linux-компилятора: GCC 3.3.4 (стабильная версия, проверенная временем, входящая в большинство современных дистрибьютивов), и Intel C++ 8.0 (далее по тексту icl), пропагандируемый как самый эффективный компилятор всех временен и народов, 30-дневная ознакомительная версия которого лежит на ftp-сервере фирмы. Для полноты картины в этот список включен древний, но все еще используемый Windows-компилятор Microsoft Visual C++ 6.0, для краткости обозначаемый как vc.

Если не оговорено обратное, приведенные примеры должны компилироваться со следующими ключами: -O3 –march=pentium3 (gcc), -O3 –mcpu=pentium4 (icl) и /Ox (vc).


Содержание раздела