SPEC CPU2000. Часть 14. Компиляторы C, C++ и Fortran компании Intel версии 8.0 в тестах SPEC CPU2000 для процессоров Intel


В начале 2003 года в тестах мы стали использовать SPEC CPU2000 версию 7.0 компиляторов компании Intel, а позже плавно перешли на 7.1. И только в конце прошлого года компания Intel представила следующую, восьмую версию своих компиляторов. В качестве одной из причин резкой смены выступило представление в начале 2004 года процессоров на новом ядре Prescott. Кроме того, что они имеют значительные архитектурные отличия от своих предшественников, в новом ядре производитель ввел новые команды в наборе инструкций SSE3.

В этой статье мы рассмотрим, что дает в плане скорости использование новой версии компилятора с процессами Intel, включая модели на ядрах Northwood, Banias и Prescott.

В тестах используются следующие версии компиляторов:

  • Intel(R) C++ Compiler for 32-bit applications, Version 8.0   Build 20040125Z Package ID: W_CC_PC_8.0.041_PE044.1
  • Intel(R) Fortran Compiler for 32-bit applications, Version 8.0   Build 20040125Z Package ID: w_fc_pc_8.0.040

Кроме того, мы еще дальше пошли по пути универсализма и использовали совершенно одинаковые ключи для всех компиляторов. Теперь они выглядят так:

PASS1_CFLAGS=   -QxN -Qipo -O3 -Qprof_gen
PASS2_CFLAGS=   -QxN -Qipo -O3 -Qprof_use

Формально можно использовать и более простой вариант:

PASS1_CFLAGS=   -Qprof_gen
PASS2_CFLAGS=   -QxN -Qipo -O3 -Qprof_use

учитывая то, что -Qipo не работает одновременно с -Qprof_gen и использование -QxN и -O3 на первом проходе может только замедлить генерацию кода и ничего не дать для скорости итогового исполняемого файла. Тем более что проведенное сравнение этих двух вариантов показало, что разницы по скорости между ними нет. Однако первый вариант используется для публикации результатов на www.spec.org другими компаниями, а искать свой путь в данном случае не обязательно. Но все равно стоило проверить подходит ли эта комбинация :).

Что касается оптимизации под различные архитектуры, то в этой версии появились новые варианты, и теперь для современных процессоров предлагается использовать ключ -Qx{W, N, B, P}. Очевидно, используются первые буквы названий ядер. Отметим, что первые три варианта работоспособны на всей современной линейке процессоров Intel Pentium, так что тем более интересно посмотреть, есть ли какие-то в них отличия по скорости.

Начнем с рассмотрения результатов тестирования нового компилятора, а потом обсудим особенности новых вариантов оптимизаций.

Intel Pentium 4 2.4

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

Для тестов была выбрана не очень быстрая система — чипсет SiS 645DX с памятью типа DDR333, но и по нынешним временам вполне достойная.

Начнем, как всегда, с целочисленной арифметики.

Во всех подтестах кроме 197.parser новый компилятор обгоняет своего предшественника на несколько процентов (для варианта с ключом -QxW и, не считая 252.eon, в котором видимо из-за замены ключей рост составил 35%). Рост интегрального показателя составил более 5%. Если сравнивать различные оптимизации в восьмом компиляторе, то получается не однозначная картина. Только два подтеста имеют заметную разницу в скорости: 176.gcc при использовании -QxN уменьшил показатель на 7%, а 181.mcf подрос на 16%. Интегральная оценка подросла всего на 0,72%. Так что в целом можно констатировать, что для данного процессора переход на новую оптимизацию практически ничего не дает. Отметим, что 181.mcf ранее зарекомендовал себя как «жадный до скорости памяти», так что возможно новая оптимизация использует тонкости организации кэша и доступа к памяти.

Что касается варианта оптимизации под Banias, то он и на обычном Pentium 4 замечательно работает и в некоторых подтестах даже оказывается эффективнее «родного» -QxN: 176.gcc +6,27%, 181.mcf +4,69% и 197.parser +6,22%.

На наборе задач с вещественной арифметикой мы наблюдаем неравномерную картину: старый компилятор выигрывает 3-4% на подтестах 191.fma3d, 301.apsi и проигрывает 3-7% на 171.swim, 177.mesa, 178.galgel и 200.sixtrack. Так что на интегральном показателе мы имеем менее одного процента разницы в пользу нового компилятора.

Сравнение оптимизаций -QxN и -QxW показывает разницу -0,17%..+0,22% и можно считать их несущественным. А вот использование -QxB явно вредит — во всех тестах этот вариант не лучше оригинальных (падение составляет до 12%, по интегральному показателю — около 3%).

Intel Pentium 4 3.06

На этом процессоре мы проверим данные, полученные для Pentium 2.4, и попробуем оценить эффективность нового компилятора при использовании технологии HT. В тестах использовался ПК с чипсетом i875 и двухканальной памятью DDR333.

По сравнению компиляторов в speed запусках в целом картина аналогична результатам процессора Pentium 2.4. Рост интегрального показателя SPECint_base2000 составил около 5%. Что касается вещественной арифметики, то есть небольшие отличия: рост в 171.swim составил 7% против 2,7% у Pentium 2.4, а вот 187.facerec снизил скорость на 9-10% против падения всего на 1% у Pentium 2.4. Но по SPECfp_base2000 разница все так же менее одного процента.

Сравнение вариантов оптимизаций -QxN и -QxW практически совпадает с вариантом для Pentium 4 2.4. Только вот 181.mcf на этом процессоре подрос с -QxN на 14%, а 176.gcc сбросил 3%.

Для оценки эффективности работы HyperThreading мы сравнили изменение показателей от запусков теста в режиме rate с параметрами -users 1 и -users 2. На диаграммах приводится % изменений от работы на двух виртуальных процессорах. Наше прошлое тестирование HT в тесте SPEC CPU2000 было в конце 2002 года, и тогда использовалась версия компилятора 5.0.1 и система с одноканальной памятью, так что результаты могут сильно отличаться. Также напоминаю, что не очень корректно использование теста SPEC CPU2000 для измерения производительности HT, поскольку одновременно запускаются одинаковые задачи, а HT больше подходит для разнородных программ.

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

Аналогичная ситуация и со вторым набором тестов. Отметим только улучшение ситуации с 171.swim, 183.equake, 301.apsi и ухудшение показателей у 177.mesa.

В целом качественных изменений по всем тестам от нового компилятора нет.

Intel Pentium M

В компиляторах версии 8.0 впервые появилась возможность оптимизации кода для ядра Banias. В тестах использовался процессор с частотой 1,5 ГГц установленный в ноутбуке «Версия». Напомним, что в Centrino используется чипсет i855 и одноканальная память типа DDR266. Мы уже видели, что использование ключа -QxB скорее вредно для обычных процессоров Pentium 4. Посмотрим теперь, дает ли что-то он для своего «родного» ядра.

Во-первых, мы видим, что компилятор версии 8.0 быстрее своего предшественника и на этом ядре со всеми вариантами оптимизаций. Отметим значительный (почти на 30%) рост у 181.mcf. При этом -QxB всегда является лучшим выбором для этого процессора, хотя и чаще всего незначительно. Рост интегрального показателя при переходе на восьмую версию компилятора составил более 8%, а преимущество «родного» перед «универсальным» ключом -QxW составляет около 4%.

На наборе задач с вещественной арифметикой мы видим заметный рост на нескольких подтестах, в частности 168.wupwise, 171.swim и 200.sixtrack. Заметим, что у Pentium 4 таких значительных изменений в этих задачах не было. А 187.facerec снова показал снижение скорости по сравнению с прошлой версией компилятора. Тем не менее, интегральный показатель в этот раз увеличился более чем на 4%. Это самый большой рост для SPECfp_base2000 среди протестированных процессоров.

Intel Pentium 3.2E (Prescott)

Процессор Pentium 4 на новом ядре был представлен компанией Intel совсем недавно, и первые измерения скорости показали очень неоднозначную картину. В частности во многих тестах он получился медленнее своего предшественника (при работе на той-же частоте). Сравнение их в тесте SPEC CPU2000 у нас будет в следующем материале, а пока посмотрим, что дает новому ядру последняя версия компилятора. С этой информацией нам будет проще анализировать результаты SPEC CPU2000 на новом ядре в дальнейшем. Конфигурация ПК: чипсет i875 с двухканальной DDR400 памятью.

Здесь мы видим, что новый компилятор во всех вариантах оптимизаций лучше старого. При этом все варианты практически равны по скорости за исключением отставания 181.mcf в варианте -QxW. По интегральной оценке преимущество нового компилятора составляет около 8%. Он значительно выигрывает в 181.mcf, 252.eon и 255.vortex.

В тестах CFP2000 мы видим резкий отрыв на 25% -QxP-оптимизированной версии в 168.wupwise который вполне может быть вызван использованием SSE3. Из остальных подтестов отметим 171.swim (+15%), 178.galgel (+16%), 172.mgrid (-9%). Изменение скорости этих задач значительно отличаются от аналогичных для Pentium 4 3.06 (там мы получили 171.swim (+7%), 178.galgel (+9%), 172.mgrid (+0,19%)). Интересно отметить, что изменения скорости у указанных подтестов наблюдается для всех вариантов оптимизаций и значит, не связаны с SSE3. Рост интегрального показателя SPECfp_base2000 составил на этом процессоре всего 2,8%.

Попробуем построить и диаграммы эффективности работы HT аналогичные полученным на Pentium 4 3.06.

Интересно, что характер изменений значительно поменялся. 164.gzip показывает значительный рост от использования HT — более 30%, тогда как Pentium 4 3,06 давал менее 20% (а на новом компиляторе еще меньше — около 10%). 176.gcc и 255.vortex перешли в класс «не страдающих» от HT. 186.mcf наоборот стал испытывать трудности и показал -10% (Pentium 4 3,06: +4%). 186.crafty, 252.eon тоже заметно сдали. Так что в целом можно отметить, что работа технологии HyperThreading на новом ядре значительно изменилась.

С тестами CFP2000 аналогичная ситуация. Отметим только ухудшение показателей у 168.wupwise и 179.art, которое привело к тому, что по интегральному показателю эффективность HT просто исчезла.

Особенности реализации оптимизаций в компиляторах Intel

Поскольку тест SPEC CPU2000 является, в том числе, и тестом компиляторов, то рассмотрение возможностей оптимизации кода представляет значительной интерес и помогает объяснить результаты теста при работе на разных процессорах.

Оптимизацию кода в компиляторах Intel можно разделить на две части: оптимизация пользовательского кода и оптимизированные библиотеки.

При этом для улучшения скорости выполнения пользовательского кода используются различные методы, как не зависимые от архитектуры процессора, так и жестко привязанные к ней. К первым относится общая оптимизация «на скорость» (-O3), межпроцедурная оптимизация (-Qipo) и профилирование (-Qprof_gen/prof_use). Второй, по сути, представлен единственным ключом -Q[a]x{K,W,N,B,P} (в версии 8.0), основное значение которого — векторизация кода с применением SIMD инструкций. Отметим, что оптимизация под Pentium MMX/Pentium II в этой версии уже не поддерживается. Есть и другие ключи оптимизации, однако они используются гораздо реже и дают меньший эффект.

Поскольку первая группа работает со всеми процессорами, то с ней вопросов не возникает. А вот со второй все гораздо интереснее.

Дальнейшее сравнение будет проходить на задачах теста SPEC CPU2000 и поэтому во многих предложениях неявно подразумевается добавление «на задачах SPEC CPU2000». Конечно, на других исходных кодах результаты могут быть другими, однако наличие в тесте большого количества разнородных задач позволяет надеяться, что мы не далеки от истины. Мы не ставили перед собой задачу досконально разобраться в особенностях работы компиляторов Intel, однако проведенные исследования помогут лучше интерпретировать результаты тестирования производительности.

Кроме того, стоит учесть, что тестирование проводилось именно с указанными в начале статьи билдами компилятора. Дело в том, что за время проведения теста они поменялись пару раз, а к моменту опубликования статьи были выпущены очередные обновления :). Конечно мы стараемся использовать именно последние версии в наших тестах, однако не всегда получается угнаться за Intel :).

Сначала посмотрим, как компилятор определяет тип процессора и где эта информация используется далее. Для этого в начале программы (на самом деле это не совсем верно, скорее так: «в любом месте программы, если при проверке типа он не известен…») вызывается одна специальная функция, которая и устанавливает внутренний флаг в зависимости от процессора. С версии компилятора 7.1 в ней стал проверяться производитель процессора и если это не Intel, то дальнейшее рассмотрение его возможностей не проводится и считается, что процессор «общего» типа.

Все три новых ключа используют новую процедуру проверки типа процессора при исполнении и при критичном не соответствии (например, код для Prescott запущен на Northwood) пользователь видит следующее сообщение:

Fatal Error : This program was not built to run on the processor in your system.

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

Отметим, что процедура инициализации кода для случая -QxW не реагирует таким фатальным образом на этот флаг, и мы легко можем получить код, использующий SSE2 и работающий на процессорах не от Intel. Другое дело, что, как мы видели ранее, для -QxN компилятор делает отличный код даже для процессора Pentium 4. И это отличие в скорости может быть существенным в некоторых задачах. Отметим, что и для -QxW и для -QxN в счетных задачах используются оптимизированные библиотечные функции (например, вычисление синуса с использованием кода SSE2), при этом проверка типа процессора не проводится. Не смотря на то, что в библиотеках есть и универсальный вариант процедуры, внутри которого стоит выбор варианта кода по типу процессора, он не используется при оптимизациях -Qax*. По крайней мере, нам не удалось добиться вызова именно универсальных процедур на коде задач SPEC CPU2000. Вместо этого компилятор создавал два варианта всего кода программы с диспетчером в ее начале. Что, в общем, тоже понятно — оптимизация самого кода под SIMD может быть существенной и поэтому лучше иметь именно две версии всего кода. Правда здесь есть одна тонкость — если процедура «простая», то есть, она в принципе выполнима на том же FPU за одну команду (тот же синус), то дело происходит так, как указано выше. Но если функция является библиотечной (например, обратная тригонометрия), то при использовании ключей -QxW/N/B вставляется прямой вызов оптимизированной под SSE2 функции, а для не SSE2 кода (работа без ключей -Qx* или альтернативный вариант для -Qax*) используется вызов библиотечной функции, в которой встроен диспетчер по типу процессора. Так что может так случиться, что программа, не предназначенная автором для работы с SSE2 (выбором ключей компиляции) тем не менее будет использовать эти команды на процессорах, которые их поддерживают (для компиляторов 7.1/8.0 — только на процессорах от Intel :) ).

Есть и другие функции, для которых компилятор не сразу вставляет в код вызов оптимизированного варианта и проверка процессора осуществляется непосредственно в них. К таким относятся в частности процедуры работы с блоками памяти (очистка, инициализация, копирование). При этом в них вызывается новая подпрограмма, которая предназначена для тонкой настройки процедур работы с блоками в памяти. Например, в ней определяются параметры кэша процессора, что позволяет использовать оптимальный для каждого случая код. Однако именно в ней еще раз проверяется производитель процессора. Но здесь эта проверка совершенно правомочна, поскольку только Intel (из ведущих производителей) поддерживает выдачу информации о кэшах процессора в необходимом виде, на основании которой и настраиваются параметры выше указанных функций.

Поскольку для современных процессоров Intel Pentium 4 можно использовать несколько вариантов ключей -Qx{W,N,B} и мы видели значительную разницу в скорости выполнения полученного кода, то получается, что в этом случае по-разному компилируется пользовательский код.

Детальное сравнение вариантов -QxW и -QxN на подтестах SPEC CPU2000 показало, что непосредственно ассемблерный код, который генерируют новые компиляторы, у них практически полностью совпадает. Например, для 164.gzip и 172.mgrid он полностью одинаковый (кроме вызова функции инициализации). Но и тех отличий, что все же есть, хватает для значительного роста показателей теста 181.mcf.

А вот сравнение ассемблерных листингов с ключами -QxN, -QxB и -QxP показало, что компилятор уже сильнее использует «настройки» на ядро: выбирает порядок команд, использует разное расположение данных в регистрах и выбирает разные заготовки для реализации некоторых функций.

Посмотрим, как обстоит дело с использованием новых инструкций SSE3 для процессора Pentium 4 Prescott. Исследование тестов SPEC CPU2000 показало, что инструкции из этого набора действительно используются для пользовательского кода, хотя и не все тринадцать.

  MOVSLDUPMOVSHDUPMOVDDUPADDSUBPSADDSUBPDHADDPSHSUBPSHADDPD
164.gzip         
175.vpr         
176.gcc         
181.mcf         
186.crafty         
197.parser         
252.eon        +
253.perlbmk         
254.gap         
255.vortex         
256.bzip2         
300.twolf   +    +
          
168.wupwise   + +   
171.swim   +     
172.mgrid   +    +
173.applu   +    +
177.mesa         
178.galgel   + +  +
179.art         
183.equake   +    +
187.facerec ++ + +++
188.ammp   +    +
189.lucas         
191.fma3d   +    +
200.sixtrack  +    +
301.apsi   + +  +

Заметим, что приведенные данные потенциально зависят от выбора ключей оптимизации и при другом их выборе могут измениться. Очень отличается и частота использования инструкций. Например, в 187.facerec MOVSLDUP встречается буквально один раз, а MOVDDUP в 168.wupwise гораздо чаще. Что касается кода библиотечных функций, то (в настоящий момент и для тестов SPEC CPU2000) SSE3 там, скорее всего, не используется.

Выводы

Компиляторы версии 8.0 показали прирост производительности на тестах SPEC CPU2000 по сравнению с прошлой версией. Отметим, что рост не такой уж и большой — около 5% на SPECint_base2000. Больший интерес представляет появление оптимизаций под процессор Pentium M Banias и, конечно, Pentium 4 Prescott. Для первого использование «правильного» кода дает в нескольких подтестах прибавку в 10-15 процентов. Заметим, что это касается и задач с вещественной арифметикой. Появление новой опции для процессоров Pentium 4 (-QxN) выглядит немного странно, так как их ядро уже практически сошло со сцены. Тем более что заметного эффекта она не дает. Только два подтеста CINT2000 явно отреагировали на нее.

Поскольку Intel старается не оставлять свои процессоры без программной поддержки, то появление оптимизации под Prescott (-QxP) выглядит вполне естественно. При этом, как мы видели, используются новые инструкции SSE3 для пользовательского кода. Заметный эффект от их использования (+25%) наблюдается только в 168.wupwise. Во всех остальных задачах скорость практически совпадает с результатом -QxN.

Что касается введенной проверки производителя процессоров, на наш взгляд все не так плохо — в любом случае остается вариант использования ключа -QxW, который включает поддержку SSE/SSE2. Да и обвинять Intel в том, что она «затачивает» свои компиляторы под свои же процессоры, по меньшей мере, глупо. Тем более что процессоры отличаются не только «фичами» и наборами команд, но и внутренней архитектурой (алгоритмами работы блоков предсказания, префетча, кэшей и т.п.). И такой ход вполне разумен и может дать определенные дивиденды для скорости работы кода.

Кстати напомним, что другим производителям процессоров тоже можно было бы сделать свой компилятор. Или, в крайнем случае, вместе с Intel реализовать эффективную поддержку своих продуктов в ее компиляторе :).

А для тестеров сложившаяся ситуация означает только одно — теперь процессоры разных компаний будут тестироваться на существенно разном коде. Что, в целом, не очень хорошо. Хотя синтетика — она и в Африке синтетика :).




Дополнительно

iXBT BRAND 2016

«iXBT Brand 2016» — Выбор читателей в номинации «Процессоры (CPU)»:
Подробнее с условиями участия в розыгрыше можно ознакомиться здесь. Текущие результаты опроса доступны тут.

Нашли ошибку на сайте? Выделите текст и нажмите Shift+Enter

Код для блога бета

Выделите HTML-код в поле, скопируйте его в буфер и вставьте в свой блог.