"Генерация высококачественного кода для программ, написанных на СИ" - читать интересную книгу автора (Хислей Филипп Н.)

Тестирование компиляторов

PC Tech Journal разработал тест оптимизации Си (см. листинг 1) как подспорье в оценке оптимизационных возможностей компиляторов Си. Тест проверяет степень оптимизации, проводимой компилятором. Для обеспечения основы для сравнения измерений времени выполнения для каждого компилятора запускался тест исполнения PC Tech Journal с ключами, разрешающими оптимизацию. Результаты его работы для каждого компилятора суммируются в таблице 1. Рисунок 6 демонстрирует опции оптимизации для каждого компилятора, которые использовались при компиляции обоих тестов. Характеристики выполнения программ можно сравнить с измерениями без оптимизации, приведенными в февральском номере за 1988 год (см. стр. 62 и 80).

Целью обоих тестов, исполнения и оптимизации, было получить наиболее быстрый код, который может дать каждый компилятор. Если компилятор предоставляет опции для генерации кода, они выбирались с приоритетом времени выполнения над размером программного кода, генерировались команды микропроцессора 80286 и непосредственные команды сопроцессора 80287, запрещалось проверять переполнение стека. Таким образом, минимальная конфигурация системы, требуемая для запуска тестов в том виде, в каком они компилировались, - машина с процессором 80286 и математическим сопроцессором 80287.

Многие компиляторы также имеют опции для генерации кода процессоров 80186 и NEC V20/V30, которые могут использоваться для машин класса XT (см. "Chips in transitions", Bob Smith, апрель 1986г., стр. 56). Эти процессоры имеют большинство средств 80286, исключая команды защищенного режима, так что сгенерированный для них код совпадает с кодом для 80286.

----------------------------------------------------¬

¦РИСУНОК 6: Командные строки ¦

+---------------------------------------------------+

¦ ¦

¦ BORLAND TURBO C 1.5 ¦

¦ : tcc -1 -f87 -N- -S -O -G -Z -r optbench.c ¦

¦ ¦

¦ COMPUTER INNOVATIONS C86PLUS 1.10 ¦

¦ : cc -DNO_ZERO_DIVIDE=1 -c -FPi87 -Oatx ¦

¦ -G2 -Fa optbench.c ¦

¦ ¦

¦ DATALIGHT OPTIMUM-C 3.14 ¦

¦ : dlc1 optbench.c -f-g ¦

¦ dlg optbench.tmp +vbe +all ¦

¦ dlc2 optbench.tmo ¦

¦ ¦

¦ LATTICE MS-DOS C 3.2 ¦

¦ : lc -d -k2 -f -v optbench.c ¦

¦ ¦

¦ MANX AZTEC C86 4.0 ¦

¦ : cc -A +A -B -T +F +2 +ef optbench.c ¦

¦ ¦

¦ METAWARE HIGH C 1.4 ¦

¦ : hc optbench.c -def NO_ZERO_DIVIDE=1 ¦

¦ pragma Off(Check_stack, Check_subscript) ¦

¦ pragma On(286, asm, auto_reg_alloc) ¦

¦ pragma On(floating_point, optimize_xjmp) ¦

¦ pragma On(optimize_xjmp_space, use_reg_vars) ¦

¦ ¦

¦ MICROSOFT C 5.0 ¦

¦ : cl -DNO_ZERO_DIVIDE=1 -c -G2 -Fc ¦

¦ -Ox optbench.c ¦

¦ ¦

¦ MICROSOFT QUICKC 1.0 ¦

¦ : qcl -c -G2 -FPi87 -Ox d:\optbench.c ¦

¦ ¦

¦ WATCOM C 6.0 ¦

¦ : wcc d:\optbench.c /d1 /oilt /s /2 /7 ¦

+---------------------------------------------------+

¦ Выполняемый код для тестов оптимизации и ¦

¦ исполнения, которые использованы в этой статье, ¦

¦ генерировался с помощью этих командных строк с ¦

¦ указанными директивами компиляторов. ¦

L----------------------------------------------------

Результаты теста исполнения для каждого компилятора в малой и большой моделях памяти приводятся в таблице 1. Тесты в наборе теста исполнения организованы в функции, которые вызывались из главной управляющей процедуры. Весь набор был скомпилирован и отредактирован в один файл EXE. Некоторые из процедур теста выполняются так быстро, что единственный вызов функции невозможно точно измерить. В этих случаях функции вызываются из управляющей процедуры многократно, чтобы увеличить время выполнения для получения возможности количественных измерений. В таблице 1 приводится количество итераций для каждого теста.

--------------------------------------------------------------¬

¦Таблица 1: Результаты оптимизированного теста выполнения ¦

+-------------------------------------------------------------+

¦ COMPUTER ¦

¦ BORLAND INNOVATIONS DATALIGHT ¦

+----------------------T------------T------------T------------+

¦КОМПИЛЯТОР ¦ Turbo C ¦ C86Plus ¦ Optimum-C ¦

+----------------------+------------+------------+------------+

¦ВЕРСИЯ ¦ 1.5 ¦ 1.10 ¦ 3.14 ¦

+----------------------+------------+------------+------------+

¦ЦЕНА ¦ $99.95 ¦ $497 ¦ $139 ¦

+----------------------+------------+------------+------------+

¦РАЗМЕР ПРГРАММЫ(KB) ¦ 35/40 ¦ 30/38 ¦ 33/40 ¦

+----------------------+------------+------------+------------+

¦ОБЩИЕ ОПЕРАЦИИ (*) ¦ ¦ ¦ ¦

¦Вызовы функций ¦ 6.0/7.2 ¦ 7.6/8.2 ¦ 6.0/7.6 ¦

¦Целочисл. арифметика ¦ 7.0/7.0 ¦ 8.5/8.5 ¦ 6.3/6.3 ¦

¦Арифм-ка длинных целых¦ 29.0/29.0 ¦ 23.4/23.9 ¦ 26.3/26.9 ¦

¦Индексация ¦ 7.9/9.9 ¦ 7.9/11.4 ¦ 5.9/7.9 ¦

¦Использ-е указателей ¦ 6.2/15.3 ¦ 12.9/19.2 ¦ 6.8/15.3 ¦

¦ С регистровыми ¦ ¦ ¦ ¦

¦ переменными ¦ 6.8/15.2 ¦ 10.3/19.8 ¦ 6.8/15.3 ¦

¦Решето (Sieve) ¦ 5.0/5.0 ¦ 5.8/5.8 ¦ 4.3/3.8 ¦

¦ С регистровыми ¦ ¦ ¦ ¦

¦ переменными ¦ 6.4/6.5 ¦ 4.6/4.6 ¦ 4.3/3.8 ¦

+----------------------+------------+------------+------------+

¦ОПЕРАЦИИ С ФАЙЛАМИ ¦ ¦ ¦ ¦

¦Чтение и запись (**) ¦ ¦ ¦ ¦

¦ С дискеты на дискету¦ 8.2/8.2 ¦ 8.3/8.3 ¦ 8.3/8.2 ¦

¦ С жесткого диска ¦ ¦ ¦ ¦

¦ на жесткий диск ¦ 3.9/3.4 ¦ 3.9/3.9 ¦ 3.9/3.3 ¦

¦Getc и putc (***) ¦ ¦ ¦ ¦

¦ С дискеты на дискету¦ 49.8/50.6 ¦ 45.6/50.1 ¦ !13.5!/49.4¦

¦ С жесткого диска ¦ ¦ ¦ ¦

¦ на жесткий диск ¦ 17.6/18.4 ¦ 18.9/21.1 ¦ !5.5!/17.3 ¦

+----------------------+------------+------------+------------+

¦ОПЕРАЦИИ 80x87 ¦ ¦ ¦ ¦

¦Сложение/умножение (*)¦ 3.1/3.1 ¦ 2.8/2.8 ¦ 3.1/3.1 ¦

¦Нат. логарифм (****) ¦ 1.0/1.0 ¦ 1.3/1.3 ¦ 1.3/1.2 ¦

¦Синус/тангенс(****) ¦ 1.1/1.1 ¦ 1.5/1.5 ¦ 1.2/1.3 ¦

+----------------------+------------+------------+------------+

¦ Время измерялось в секундах и приводится для ¦

¦ малой/большой моделей памяти. ¦

¦ Тесты выполнялись на IBM PC/AT с тактовой частотой 6 ¦

¦ мегагерц, с сопроцессором 80287, с параметрами в ¦

¦ CONFIG.SYS FILES = 20 и BUFFERS = 20. ¦

¦ Значения, входящие в 10%-ю окрестность лучшего ¦

¦ результата, заключены в восклицательные знаки. ¦

¦ * - 20 итераций, ** - 1 итерация, *** - 2 итерации, ¦

¦ **** - 10 итераций. ¦

L--------------------------------------------------------------

 

--------------------------------------------------------------¬

¦Таблица 1: Продолжение ¦

+-------------------------------------------------------------+

¦ ¦

¦ LATTICE MANX METAWARE MICROSOFT WATCOM ¦

+---------T---------T---------T---------T---------T-----------+

¦MS-DOS C ¦Aztec C ¦High C ¦ C ¦QuickC ¦WATCOM C ¦

+---------+---------+---------+---------+---------+-----------+

¦3.2 ¦4.0 ¦1.4 ¦5.0 ¦1.0 ¦6.0 ¦

+---------+---------+---------+---------+---------+-----------+

¦$500 ¦$499 ¦$595 ¦$450 ¦$99 ¦$295 ¦

+---------+---------+---------+---------+---------+-----------+

¦34/41 ¦20/24 ¦33/44 ¦28/39 ¦31/44 ¦25/30 ¦

+---------+---------+---------+---------+---------+-----------+

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦7.5/8.1 ¦7.9/8.6 ¦6.9/9.5 ¦6.1/6.0 ¦6.5/7.5 ¦!3.8/4.5! ¦

¦7.7/7.7 ¦9.1/9.2 ¦5.8/5.8 ¦5.3/5.2 ¦6.8/6.8 ¦!3.7/3.8! ¦

¦23.3/24.3¦23.9/24.2¦27.8/29.1¦23.9/24.8¦27.8/28.7¦!20.0/21.0!¦

¦11.0/34.9¦9.0/10.5 ¦7.1/7.8 ¦!4.8!/7.2¦7.9/11.3 ¦5.4/!5.5 ¦

¦12.3/58.5¦12.8/15.3¦5.4/15.3 ¦!5.1!/9.8¦7.8/17.8 ¦6.1/!6.2! ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦12.8/58.6¦7.8/15.3 ¦!5.2!/15.3!5.1!/9.8¦7.7/17.8 ¦5.6/!6.2! ¦

¦7.1/6.9 ¦7.6/7.6 ¦5.4/5.6 ¦4.2/4.3 ¦5.3/5.4 ¦!3.2/3.4! ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦6.9/7.0 ¦5.9/6.1 ¦5.8/6.0 ¦4.2/4.3 ¦6.5/6.5 ¦!3.2/3.4! ¦

+---------+---------+---------+---------+---------+-----------+

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦8.2/8.2 ¦8.3/8.2 ¦8.0/8.0 ¦8.3/8.2 ¦8.2/8.3 ¦8.2/8.2 ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦3.9/3.7 ¦3.9/2.8 ¦!1.0/0.9!¦3.3/3.8 ¦3.9/3.4 ¦3.4/3.4 ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦51.3/51.5¦28.6!27.7!39.8/39.8¦40.0/40.0¦40.0/40.0¦51.2/51.3 ¦

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦21.0/26.0¦12.5!11.0!16.0/15.2¦14.8/15.7¦16.1/16.0¦19.2/20.1 ¦

+---------+---------+---------+---------+---------+-----------+

¦ ¦ ¦ ¦ ¦ ¦ ¦

¦4.7/4.7 ¦2.6/2.6 ¦2.6/2.1 ¦!1.7/1.7!¦3.1/3.0 ¦1.8/1.8 ¦

¦1.3/1.3 ¦1.1/1.1 ¦1.1/1.2 ¦1.0/1.0 ¦1.2/1.3 ¦!0.9/0.9! ¦

¦1.9/1.9 ¦1.3/1.3 ¦1.1/1.2 ¦1.1/1.1 ¦1.3/1.4 ¦!1.0/1.0! ¦

+---------+---------+---------+---------+---------+-----------+

¦ Компиляторам задавались ключи для оптимизации по ¦

¦ скорости, использования непосредственных инструкций ¦

¦ процессоров 80286 и 80287. Все тесты, интенсивно ¦

¦ использующие процессор, были выиграны компиляторами ¦

¦ WATCOM и Microsoft. Не нашлось компилятора, код которого ¦

¦ для тестов ввода/вывода выполнялся бы во время, близкое к ¦

¦ лучшему, в малой и в большой моделях памяти одновременно. ¦

L--------------------------------------------------------------

При сравнении результатов в таблице 1 и в номере за февраль 1988 необходимо отметить одно изменение. Два теста с использованием регистровых переменных (использования указателей и "решето"-sieve) в феврале были измерены для 100 итераций, а не для 20-ти. Поскольку полезно непосредственное сравнение тестов с использованием регистровых переменных и без их использования, тесты с регистровыми переменными в данном случае запускались с 20-ю итерациями. Также заметьте, что численные тесты, присутствующие в таблице 1, выполнялись для прямого кода процессоров 80x87 в малой и большой моделях памяти, а не с помощью программного эмулятора.

Поскольку текст теста оптимизации предназначен для проверки наличия или отсутствия отдельных типов оптимизации, он состоит из набора отдельных, не связанных фрагментов программ, и не представляет собой целостное, проблемно-ориентированное тело программы. Тест организован как основная функция (main), содержащая большинство фрагментов кода для оптимизации, и несколько отдельных функций, с аргументами или без них. Эти функции демонстрируют не только отдельные методы оптимизации, но также оптимизацию пролога и эпилога выполняемых функций. С целью обеспечения максимальных возможностей для оптимизации, основанной на времени жизни отдельной переменной, большинство переменных теста являются глобальными. Многие возможности обеспечены специально для общих методов оптимизации, таких как удаление лишних сохранений (присваиваний), размножение констант и размещение переменных в регистрах.

Процесс оптимизации кода сложен, и степень повышения эффективности зависит не только от типа и изощренности методов оптимизации компилятора, но также и от того, как исходный текст программы написан и структурирован. Результат также зависит от того, как в исходном тексте используются переменные и выражения.

В таблице 2 собрана информация о том, какие приемы оптимизации выполнялись каждым компилятором на тексте теста. Каждый компилятор из рассматриваемого набора выполняет простейшие приемы оптимизации, такие как свертка констант и алгебраические упрощения. Большинство применяют методы оптимизации некоторого промежуточного уровня, включающего снижение мощности и удаление общих подвыражений. Некоторые выполняют оптимизацию высокого уровня, такую как вынесение инвариантного кода и удаление переменных индукции циклов. Ни один не выполняет успешно слияние циклов, и только Datalight Optimum-C делает попытки, далеко не удовлетворительные, применения глубокого удаления общих подвыражений.

--------------------------------------------------------------¬

¦Таблица 2: Результаты теста оптимизации ¦

+-------------------------T---T---T---T---T---T---T---T---T---+

¦ КОМПИЛЯТОР ВЕРСИЯ ¦ 1 ¦ 2 ¦ 3 ¦ 4 ¦ 5 ¦ 6 ¦ 7 ¦ 8 ¦ 9 ¦

+-------------------------+---+---+---+---+---+---+---+---+---+

¦МЕТОДЫ ОПТИМИЗАЦИИ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦Свертка констант (целых) ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦

¦Свертка констант (плав.) ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦

¦Размножение констант ¦ ¦ ¦ * ¦ ¦ ¦ * ¦ * ¦ ¦ * ¦

¦Размножение копий ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ ¦ * ¦

¦Алгебр.упрощения ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦

¦Подавление деления на 0 ¦ ¦ * ¦ ¦ ¦ ¦ * ¦ * ¦ ¦ * ¦

¦Удаление подвыражений ¦ ¦ ¦ * ¦ * ¦ * ¦ * ¦ * ¦ ¦ * ¦

¦Снижение мощности ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦

¦Удаление излишних ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ загрузок/сохранений ¦ * ¦ ¦ * ¦ * ¦ * ¦ * ¦ * ¦ ¦ * ¦

¦Удаление недостижи- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ мого кода ¦ * ¦ * ¦ * ¦ * ¦ ¦ * ¦ * ¦ ¦ * ¦

¦Удаление излишних ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ присваиваний ¦ ¦ * ¦ * ¦ ¦ ¦ * ¦ * ¦ ¦ * ¦

¦Использ. машинно- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ зависимых команд ¦ ¦ * ¦ ¦ * ¦ ¦ * ¦ * ¦ * ¦ * ¦

¦Поддержка встроенных ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ функций ¦ ¦ ¦ ¦ ¦ ¦ ¦ * ¦ ¦ * ¦

¦Размещение переменных ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ в регистрах ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦

¦Непосредственные инструк-¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ ции 80287 ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ * ¦ ¦ * ¦

¦Сжатие цепочки переходов ¦ * ¦ ¦ * ¦ * ¦ ¦ * ¦ * ¦ ¦ * ¦

¦Вынесение инвариантного ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ кода ¦ ¦ ¦ ¦ ¦ ¦ ¦ * ¦ ¦ ¦

¦Удаление переменных ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦ индукции циклов ¦ ¦ ¦ ¦ ¦ ¦ ¦ * ¦ ¦ ¦

¦Удаление циклов ¦ ¦ ¦ ¦ ¦ ¦ ¦ * ¦ ¦ ¦

¦Удал. глуб. подвыражений ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦Разворачивание циклов ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

¦Слияние циклов ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦

+-------------------------+---+---+---+---+---+---+---+---+---+

¦ 1 - BORLAND Turbo C 1.5, 2 - COMPUTER INNOVATIONS ¦

¦ C86Plus 1.1, 3 - DATALIGHT Optimum-C 3.14, 4 - LATTICE ¦

¦ MS-DOS C 3.2, 5 - MANX Aztec C 4.0, 6 - METAWARE High C ¦

¦ 1.4, 7 - MICROSOFT C 5.0, 8 - MICROSOFT QuickC 1.0, 9 - ¦

¦ WATCOM C 6.0. ¦

¦ * - компилятор применяет этот метод оптимизации. ¦

+-------------------------------------------------------------+

¦ Большинство включенных в обзор компиляторов языка Си ¦

¦ поддерживают простые методы оптимизации, такие как ¦

¦ алгебраические упрощения, и только несколько компиляторов ¦

¦ применяют более сложные формы, такие как удаление общих ¦

¦ подвыражений. ¦

L--------------------------------------------------------------