Результаты lame-тестов на моей машине так заинтриговали меня, что немедленно по размещении итогов предыдущего тура к месту дислокации машины на Athlon-XP/1800+, конфигурация которого была описана в статье о первом туре. И повторил - к сожалению, до того, как ознакомился с соображениями Георгия Шаповалова в нашем форуме, описанными в предыдущей статье. Картина получилась довольно показательная.
Итак, на этой машине имелся Red Hat 9, уцелевший после 1-го тура, содержащий в себе ядро 2.4.20 и gcc
3.2.2. На этом хозяйстве был последовательно собран lame
с теми же настройками, что и на моей: уровни оптимизации -O0
, -O1
, -O2
без всяких дополнительных флагов, сборка lame
по умолчанию - напомню, она выполняется с флагами
CFLAGS="-O3 -fomit-frame-pointer \
-ffast-math -funroll-loops \
-Wall -pipe"
сборка с флагами
CFLAGS="-O3 -march=i686"
и две сборки конкретно под Athlon-XP. В первой задействовался стандартный сопроцессор:
CFLAGS="-O3 -march=athlon-xp \
-fomit-frame-pointer \
-funroll-loops -pipe \
-mfpmath=387"
Во второй - флаги для мультимедиа-инструкций:
CFLAGS="-O3 -march=athlon-xp \
-fomit-frame-pointer
-funroll-loops -pipe \
-mfpmath=sse -mmmx -msse -m3dnow"
В связи с замечанием Георгия скажу пару слов о том, откуда взялся флаг -funroll-loops
. Происхождение его - чисто эмпирическое, в цикле статей о тестировании процессоров на iXBT (недавно узнал, что в народе его, оказывается, ласково называют Хоботом - спасибо @lexb за информацию) было отмечено, что снятие его приводит к провалу производительности (в том числе на AMD64), а поскольку проверять это мне было лень, решил, что джентльменам верят на слово. Впрочем, как показано в конце предыдущей статьи ко 2-й интермедии, рояля это не играет...
Как и ранее, после каждой сборки lame
трижды выполнялось конвертирование WAV -> MPEG все того же 750-мегабайтного файла (исключение - для сборки при -O0
, причину вы легко поймете, взглянув на таблицу). Как и в первый раз, результаты по lame продемонстрировали просто потрясающую воспроизводимость - в каждой серии отличий более чем на секунду не отмечалось - что в CPU time, что в Real time. Зато здесь я впервые заметил разницу между CPU time и Real time: первое было меньше стабильно на 2-3 секунды. Поскольку результаты по CPU time показали суммарно лучшую воспроизводимость, в таблице и на диаграммах использованы именно они (напомню, что в первом lame-тесте оба показателя были просто идентичны).
Вот, собственно, и все о тестах - далее предлагаю обратиться к таблице (по указанной выше причине я решил ограничиться только сравнением "средних" значений) и диаграмме.
Таблица. Сравнение средних | |
-O0 | 00:13:55 |
-O1 | 00:05:07 |
-O2 | 00:05:01 |
Default -O3 | 00:04:57 |
-O3 -march=i686 | 00:04:28 |
-O3 -march=athlon-xp/387 | 00:04:28 |
-O3 -march=athlon-xp/sse | 00:04:32 |
Имеющий глаза все увидит сам, но не откажу себе в удовольствии кратко описать картину:
- резкое повышение быстродействия при применении хоть какой-то оптимизации - разница между
-O0
и-O1
- более чем в два с половиной раза; - едва, но все же заметный, рост производительности от
-O1
до-O3
чистого; - ощутимый прирост скорости при переходе к
-O3 -march=i686
, составивший почти полминуты; - абсолютно совпадающий с ним результат для
-O3 -march=athlon-xp
с задействованием 387;
и, опять же, чуть видимое, но все же - видимое, падение при переходе к сочетанию -march=athlon-xp
с наборами sse-типа.
То есть качественно картина практически аналогична полученной для Pentium-4, за исключением отдельных деталей. Так, быстрый сопроцессор Athlon'а помешал, видимо, флагу -funroll-loops
отъесть у него производительности. Большие абсолютные значения времени кодирования (все же реально здесь было на один гигагерц меньше, чем на моем агрегате) выявили чуть заметные отличия при уровнях оптимизации -O1
, -O2
и -O3
. И инструкции sse-типа повредили Athlon'у не так сильно, как "четверке" :-)). Однако все остальное вполне укладывается в наметившуюся ранее тенденцию. Что позволяет сделать уже более определенные выводы.
Помните, как Атос во время завтрака при возвращении в Париж (после истории с подвесками) спросил своих товарищей, что они едят? И когда в ответ те начали расписывать изыски французской кулинарии, возразил: "Господа, вы едите конину. Может быть, даже с седлом".
Так вот, господа, сидящие за крутейшими "четверками" и Athlon'ами и воображащие себя пожирателями трюфелей и омаров (не обижайтесь, это я и про себя). Вы работаете за PentiumPro. Может быть, даже без инструкций mmx/sse
... И отсюда - первый вывод: единственные флаги оптимизации, в общем случае окупающие усилия пальцев по их вводу и амортизацию клавиатуры - это
CFLAGS="-O3 -march=i686"
А все остальное, включая mmmx/msse/msse2, способно в лучшем случае не очень ухудшить быстродействие.
Отдельно - о флагах из области mmx/sse. Теоретически они должны бы дать прирост быстродействия. Однако для этого, как резонно заметил Георгий, собираемая с ними программа должна знать о существовании таких инструкций. А похоже, что большинство программ (даже таких, как lame
, которой они могли бы принести пользу - чему примером виндовые аналоги) об этом и не подозревают.
И - к слову сказать, правильно делают. Мне всегда казалось, что подмена универсальных инструкций специализированными если и даст сиюминутную выгоду, в долгосрочной перспективе не оправдана: а как завтра Intel выдумает новый набор, mega-sse#? Тогда как старый добрый сопроцессор - он и в Африке сопроцессор...
Второй вывод: пример lame
убеждает, что есть программы, не оптимизируемые под процессор (или процессоры, под которые некоторые программы оптимизировать бессмысленно?). Однако мы знаем примеры и противного: ведь те 30 процентов для gcc
, полученные таким образом Джастин Piszcz (фамилию транскрибировать не рискну:-))- это реальность (ну пусть не 30, но 10-15% - тоже хороший результат).
Остается определить, для каких программ жесткая оптимизация оправданна, а для каких - может даже и повредить. Решать эту проблему я предлагаю методом общенародного супермегатестирования. Для чего отнюдь не требуется где-то собираться и чего-то всем миром мучать. Достаточно, если каждый заинтересованный пришлет результаты измерений по какой-либо важной для него (или просто любимой) софтине - при сборке по умолчанию и при компиляции с различными флагами. Из чего со временем и составится общедоступная база данных оптимизируемых программ (или - не оптимизируемых, помните, что в данном случае отрицательный результат - тоже результат).