SPEC CPU2000. Часть 20. Компиляторы Intel C++/Fortran Compiler 9.0, процессоры Intel Pentium 4 670, Pentium M 770 и AMD Athlon 64 FX-57


В середине июня компания Intel представила новую, девятую версию своих компиляторов C++ и Fortran. Новую версию компиляторов нельзя назвать принципиально иной по сравнению с предыдущей версией 8.1, ее основные особенности — это интеграция компиляторов для платформ IA-32, IA-64 и EM64T (x86-64) в единый пакет, а с точки зрения оптимизации кода — дополнительные опции для процессоров с технологией Hyper-Threading и многоядерных процессоров, в частности, спекулятивной загрузки данных из памяти в отдельно создаваемом потоке (Software-based Speculative Pre-Computation, SSP).

В настоящей статье мы рассмотрим, насколько эффективна в плане скорости новая версия компиляторов по сравнению с предыдущей на топовых (или почти топовых) одноядерных процессорах — как Intel (Pentium 4 и Pentium M), так и… AMD (Athlon 64 FX-57 — разумеется, с некоторой «доработкой» кода, о чем ниже).

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

  • Intel(R) C++ Compiler for 32-bit applications, Version 9.0 Build 20050624Z Package ID: W_CC_C_9.0.020
  • Intel(R) Fortran Compiler for 32-bit applications, Version 9.0 Build 20050624Z Package ID: W_FC_C_9.0.019

В качестве «эталона сравнения» использовался код тестов, откомпилированный ранее с помощью Intel C++ Compiler 8.1.022 и Intel Fortran Compiler 8.1.025.

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

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

Pentium 4 670

Начнем с результатов «родного» для компиляторов процессора — Pentium 4 670 (частота 3.8 ГГц) с ядром Prescott, поддерживающего все необходимые наборы инструкций и позволяющего запускать код, откомпилированный со всеми возможными ключами специфических оптимизаций: -QxK, -QxW, -QxN, -QxB и -QxP.

 Без опт.-QxK-QxW-QxN-QxB-QxP
ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0
164.gzip11501130
(-1.7%)
12531239
(-1.1%)
12551248
(-0.6%)
12651251
(-1.1%)
-124712671241
(-2.1%)
175.vprxx12071201
(-0.5%)
12901283
(-0.5%)
12881272
(-1.2%)
-125512861270
(-1.2%)
176.gccxx21422119
(-1.1%)
21322122
(-0.5%)
21462125
(-1.0%)
-211621552116
(-1.8%)
181.mcf15951594
(-0.1%)
15991599
(0.0%)
15981600
(0.1%)
21252125
(0.0%)
-211321312115
(-0.8%)
186.crafty12511260
(0.7%)
12721285
(1.0%)
13711398
(2.0%)
13751406
(2.3%)
-138713871389
(0.1%)
197.parser15531030
(-33.7%)
15621031
(-34.0%)
15621026
(-34.3%)
15601025
(-34.3%)
-101915601031
(-33.9%)
252.eon16401762
(7.4%)
17951836
(2.3%)
21882153
(-1.6%)
23912360
(-1.3%)
-210123592320
(-1.7%)
253.perlbmk19972021
(1.2%)
19542015
(3.1%)
19232012
(4.6%)
19401991
(2.6%)
-201819472006
(3.0%)
254.gap20332110
(3.8%)
19361990
(2.8%)
20192035
(0.8%)
20222061
(1.9%)
-202920322049
(0.8%)
255.vortex28762941
(2.3%)
28712971
(3.5%)
28692970
(3.5%)
28542970
(4.1%)
-285228332948
(4.1%)
256.bzip214231428
(0.4%)
13901399
(0.6%)
13781372
(-0.4%)
13601348
(-0.9%)
-135413721415
(3.1%)
300.twolf18671526
(-18.3%)
18401880
(2.2%)
18591898
(2.1%)
18651910
(2.4%)
-187918691908
(2.1%)
SPECint_base200016821604
(-4.6%)
16821642
(-2.4%)
17341687
(-2.7%)
17901739
(-2.8%)
-170817921739
(-3.0%)
 
168.wupwise18821843
(-2.1%)
20312074
(2.1%)
22352304
(3.1%)
21981735
(-21.1%)
-176228602914
(1.9%)
171.swim20892088
(0.0%)
23622544
(7.7%)
25242596
(2.9%)
25252595
(2.8%)
-255325262595
(2.7%)
172.mgrid10221023
(0.1%)
12371216
(-1.7%)
15181511
(-0.5%)
16741661
(-0.8%)
-130616751661
(-0.8%)
173.applu14191438
(1.3%)
14041414
(0.7%)
14811472
(-0.6%)
16551670
(0.9%)
-155516381691
(3.2%)
177.mesa13991371
(-2.0%)
14961476
(-1.3%)
16661669
(0.2%)
16621668
(0.4%)
-157416591653
(-0.4%)
178.galgel14451440
(-0.3%)
30363119
(2.7%)
35813637
(1.6%)
35643866
(8.5%)
-362636033889
(7.9%)
179.art27162356
(-13.3%)
23702393
(1.0%)
29182613
(-10.5%)
29872655
(-11.1%)
-252446484597
(-1.1%)
183.equake20742105
(1.5%)
21432118
(-1.2%)
21552154
(0.0%)
21582148
(-0.5%)
-209221562420
(12.2%)
187.facerec17361773
(2.1%)
20352148
(5.6%)
20492151
(5.0%)
20372165
(6.3%)
-211420752179
(5.0%)
188.ammp13051226
(-6.1%)
12401213
(-2.2%)
13651345
(-1.5%)
13711346
(-1.8%)
-121013691346
(-1.7%)
189.lucas21092101
(-0.4%)
20072025
(0.9%)
22852320
(1.5%)
22792331
(2.3%)
-198423022306
(0.2%)
191.fma3d13161342
(2.0%)
12911342
(4.0%)
16001648
(3.0%)
15811683
(6.5%)
-137116061646
(2.5%)
200.sixtrack604606
(0.3%)
597605
(1.3%)
678754
(11.2%)
679746
(9.9%)
-621683748
(9.5%)
301.apsi13091277
(-2.4%)
13171301
(-1.2%)
13861370
(-1.2%)
14081357
(-3.6%)
-130014101357
(-3.8%)
SPECfp_base200015111489
(-1.5%)
16361657
(1.3%)
18261842
(0.9%)
18541845
(-0.5%)
-169019562007
(2.6%)

Но начнем, тем не менее, с неоптимизированного варианта. Сразу отметим одну важную деталь: эта версия кода, откомпилированная как предыдущей, так и новой версией компилятора, вызывала ошибки в подтестах 175.vpr и 176.gcc — независимо от типа используемого процессора. В связи с чем, мы использовали --noreportable вариант запуска тестов, позволяющий игнорировать ошибки в отдельных подтестах (--ignore_errors). Итак, целочисленные тесты. Новая версия позволяет получить некоторое преимущество в ряде подтестов (252.eon, 253.perlbmk, 254.gap, 255.vortex), которое, однако, невозможно компенсировать значительным снижением производительности 197.parser (порядка 34%!), а также 300.twolf. В результате имеем общую оценку SPECint_base2000 = 1604, на 4.6% уступающую оценке, полученной с версией 8.1 (1682). В тестах с вещественными числами новая версия позволяет получить лишь едва заметное преимущество по скорости в ряде подтестов, но и здесь не обошлось без заметного снижения скорости отдельных подтестов (13.3% в 179.art). В результате, общая оценка SPECfp_base2000 (1489) на 1.5% уступает результату, полученному с предыдущей версией (1511).

Следующий вариант оптимизации, использующий инструкции SSE (-QxK). В целочисленных тестах наблюдаем аналогичную картину — незначительное преимущество новой версии в некоторых подтестах при 1.5-кратном снижении производительности 197.parser. Тем не менее, 300.twolf в этом случае отличается не только не худшей, но и даже лучшей производительностью (2.2%). Интегральная оценка примерно на 2.5% ниже по сравнению с версией 8.1. Совсем по-другому обстоит дело в тестах с плавающей точкой — производительность большинства задач возрастает при переходе к версии 9.0, максимальный прирост наблюдается в подтестах 171.swim (7.7%) и 187.facerec (5.6%). Интегральный показатель SPECfp_base2000 на 1.3% выше по сравнению с предыдущей версией.

Что касается остальных вариантов оптимизации кода (-QxW, -QxN и -QxP), в целочисленных тестах картина оказывается похожей на вариант -QxK: по-прежнему наблюдаем 1.5-кратное падение производительности 197.parser и, как следствие, несколько меньший интегральный показатель SPECint_base2000. В тестах с плавающей точкой между указанными вариантами оптимизации наблюдаются различия — как в интегральном показателе, так и в отдельных подтестах. Так, в варианте SSE2/Willamette (-QxW) заметен прирост в 200.sixtrack (11.2%) и 187.facerec (5.0%) при значительном снижении скорости 179.art (-10.5%). По SPECfp_base2000 новая версия выигрывает всего 0.9%. Вариант SSE2/Northwood (-QxN) по общей оценке, напротив, несколько проигрывает предыдущей версии (на 0.5%), благодаря значительному падению в скорости 168.wupwise (-21.1%) и том же 179.art (-11.1%) при некотором приросте в целом ряде подтестов (178.galgel, 187.facerec, 191.fma3d и 200.sixtrack). Наконец, «родной» для Prescott SSE3-вариант -QxP выигрывает 2.6% по общему показателю благодаря увеличению производительности задач 178.galgel (7.9%), 183.equake (12.2%), 187.facerec (5.0%) и 200.sixtrack (9.5%) при практически незаметном снижении скорости выполнения немногих других подтестов (максимальном — 3.8% в 300.aspi).

Абсолютная производительность как целочисленных, так и вещественных задач в целом (по интегральным показателям) возрастает в ряду -QxK < -QxB < -QxW < -QxN < -QxP, что вполне разумно для ядра Prescott.

Pentium M 770

Переходим ко второму «почти флагману» Intel — процессору Pentium M 770 с тактовой частотой ядра Dothan 2.13 ГГц. Тесты с участием этого процессора проводились на «десктопно-мобильной» системе — материнской плате DFI 855GME-MGF с не самым быстрым чипсетом Intel 855GM, а точнее — не самой быстрой подсистемой памяти (одноканальной DDR-333).

 Без опт.-QxK-QxW-QxN-QxB
ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0
164.gzip11431091
(-4.5%)
12481245
(-0.2%)
12361238
(0.2%)
12471246
(-0.1%)
-1251
175.vprxx13211316
(-0.4%)
13671381
(1.0%)
13641377
(1.0%)
-1361
176.gccxx18221805
(-0.9%)
18051803
(-0.1%)
18251806
(-1.0%)
-1814
181.mcf10421059
(1.6%)
10541052
(-0.2%)
10511047
(-0.4%)
15041507
(0.2%)
-1507
186.crafty13201303
(-1.3%)
13121313
(0.1%)
14551460
(0.3%)
14551456
(0.1%)
-1631
197.parser13811004
(-27.3%)
13921002
(-28.0%)
1392990
(-28.9%)
13881008
(-27.4%)
-1001
252.eon15891736
(9.3%)
16881668
(-1.2%)
19221930
(0.4%)
20962066
(-1.4%)
-2127
253.perlbmk17241716
(-0.5%)
17361755
(1.1%)
17501775
(1.4%)
17521760
(0.5%)
-1811
254.gap11631282
(10.2%)
11511168
(1.5%)
12801302
(1.7%)
12821298
(1.2%)
-1337
255.vortex24562484
(1.1%)
24922497
(0.2%)
24662492
(1.1%)
24912488
(-0.1%)
-2482
256.bzip212251238
(1.1%)
11561178
(1.9%)
11961176
(-1.7%)
11921178
(-1.2%)
-1205
300.twolf21021823
(-13.3%)
21112149
(1.8%)
22232252
(1.3%)
22202256
(1.6%)
-2241
SPECint_base200014591416
(-2.9%)
14891453
(-2.4%)
15441507
(-2.4%)
16051564
(-2.6%)
-1591
 
168.wupwise12491264
(1.2%)
13271356
(2.2%)
11331145
(1.1%)
11491045
(-9.1%)
-1285
171.swim713722
(1.3%)
854782
(-8.4%)
841822
(-2.3%)
845821
(-2.8%)
-821
172.mgrid777786
(1.2%)
835839
(0.5%)
817829
(1.5%)
818820
(0.2%)
-842
173.applu612617
(0.8%)
631638
(1.1%)
611608
(-0.5%)
701703
(0.3%)
-729
177.mesa898906
(0.9%)
13791506
(9.2%)
15781570
(-0.5%)
15791552
(-1.7%)
-1651
178.galgel17531694
(-3.4%)
24992503
(0.2%)
22242237
(0.6%)
22182428
(9.5%)
-2803
179.art26002495
(-4.0%)
23882360
(-1.2%)
24722437
(-1.4%)
26452575
(-2.6%)
-2634
183.equake888906
(2.0%)
905901
(-0.4%)
898898
(0.0%)
900899
(-0.1%)
-900
187.facerec11651156
(-0.8%)
12441274
(2.4%)
12371275
(3.1%)
12521273
(1.7%)
-1268
188.ammp1019980
(-3.8%)
983968
(-1.5%)
922905
(-1.8%)
904891
(-1.4%)
-963
189.lucas799809
(1.3%)
793791
(-0.3%)
891899
(0.9%)
895898
(0.3%)
-897
191.fma3d808821
(1.6%)
801812
(1.4%)
829840
(1.3%)
839853
(1.7%)
-845
200.sixtrack542540
(-0.4%)
533513
(-3.8%)
464474
(2.2%)
452475
(5.1%)
-528
301.apsi916903
(-1.4%)
916913
(-0.3%)
851853
(0.2%)
856846
(-1.2%)
-902
SPECfp_base2000963960
(-0.3%)
10381038
(0.0%)
10151018
(0.3%)
10311030
(-0.1%)
-1085

Целочисленные тесты без оптимизации кода: наибольший прирост в новой версии наблюдается в 254.gap (~10%), наиболее сильное падение — во все том же 197.parser (по сравнению с Pentium 4, оно несколько меньше — порядка 27%). Суммарная оценка SPECint_base2000 уступает предыдущей версии в среднем на 3%. В тестах с плавающей точкой наблюдается небольшой разброс значений — как в большую, так и в меньшую сторону, однако по интегральной оценке скорость выполнения кода, откомпилированного ICC/IFC 8.1 и 9.0, практически совпадает. Удивляют весьма низкие абсолютные оценки отдельных подтестов и общего показателя SPECfp_base2000 по сравнению с результатами Pentium 4 — при несильном отставании от него по целочисленным тестам. По-видимому, это связано с требовательностью этих тестов к пропускной способности памяти, которая в случае системы на базе Pentium M с одноканальной DDR-333 заметно ниже (2.67 против 6.4 ГБ/с). Но уж точно не блоком FPU, который в Pentium M реализован не только не хуже, но и намного лучше по сравнению с Pentium 4.

Использование ключей оптимизации (для данного процессора доступны -QxK, -QxW, -QxN и -QxB) не приводит к существенному изменению картины, за исключением увеличения общей производительности (которая, заметим, возрастает именно в указанном ряду, то есть «родная» оптимизация кода под ядро Banias оказывается наилучшей и для ядра Dothan). Целочисленные тесты по-прежнему немного (примерно на 2.5%) уступают предыдущей версии (благодаря заметно сниженной производительности 197.parser при одновременном отсутствии ощутимого выигрыша в остальных подтестах), а тесты с вещественными числами практически равны ей по скорости. Но последнее вновь достигается не за счет полной идентичности результатов каждого подтеста, а за счет наличия разброса величин — как в большую, так и в меньшую сторону (особенно заметного в вариантах -QxK и -QxN — до 10% в ряде подтестов), в итоге компенсирующего самого себя.

Athlon 64 FX-57

И напоследок — самое интересное! Результаты тестов компиляторов Intel C++/Fortran Compiler 8.1/9.0 на последнем одноядерном процессоре конкурента — AMD Athlon 64 FX-57. Вы спросите, как нам это удалось? Все очень просто — для этого оказалось достаточно разобраться в алгоритме проверки типа процессора кодом приложения, откомпилированного с помощью компиляторов Intel. Схематически, выглядит она следующим образом:

1. Проверка Vendor String процессора на соответствие «GenuineIntel»;

2. Определение типа модели процессора (Pentium III/Pentium M — модель 6, или Pentium 4/Xeon — модель 15);

3. Определение наличия необходимых расширенных наборов инструкций (SSE, SSE2, SSE3).

Исходя из этой схемы и простого анализа становится совершенно очевидно, что достаточно убрать проверку №1, и код, откомпилированный Intel C++/Fortran Compiler, станет работоспособным и на процессорах конкурента — при условии, что процессор поддерживает нужные наборы инструкций. Связано это с тем, что номера моделей у процессоров Intel и AMD, к счастью, совпадают: модели 6 соответствуют процессоры класса AMD K7 (большинство из которых поддерживают SSE), а модели 15 — процессоры AMD K8 (поддерживающие SSE, SSE2, а в последней ревизии ядра E — и SSE3). Впрочем, если бы этого совпадения и не было, нам ничего не мешало бы убрать и проверку №2. Тогда работоспособность приложения зависела бы только от наличия/отсутствия в процессоре необходимых расширений.

«Исправление» бинарных файлов можно осуществлять вручную, однако для этой цели мы написали небольшую вспомогательную утилиту — ICC Patcher (скачать ее можно отсюда). Она просматривает бинарный файл на предмет «подозрительных» проверок соответствия на GenuineIntel и заменяет все эти проверки пустыми операциями NOP. Заметим, что этим патчером можно «исправлять» не только готовые exe-файлы, но и исходные библиотеки Intel C++/Fortran Compiler, в том числе для EM64T. Тогда в результате компиляции всегда будут получаться программы, работоспособные как на процессорах Intel, так и AMD. Причем, повторим, такой патчинг не является «грубым» — например, код, откомпилированный с ключом -QxP, запустится только на процессорах AMD Athlon64/Opteron с ревизией ядра E, и выдаст корректное предупреждение о невозможности продолжения работы на более ранних ревизиях ядра и на процессорах класса AMD K7.

Но перейдем к результатам тестов. Из соображений экономии времени, мы решили не перекомпилировать заново все исходники тестов с «правильными» файлами библиотек Intel, а «исправить» уже имеющиеся бинарные файлы. В связи с этим, в config-файлах тестов выставлялась опция check_md5=0, ибо нетрудно догадаться, что «исправление» исполняемых файлов изменяет их контрольную сумму.

 Без опт.-QxK-QxW-QxN-QxB-QxP
ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0ic8.1ic9.0
164.gzip14371363
(-5.1%)
15681571
(0.2%)
15461546
(0.0%)
15661540
(-1.7%)
-158415741558
(-1.0%)
175.vprxx14291406
(-1.6%)
15151510
(-0.3%)
15161503
(-0.9%)
-148315141486
(-1.8%)
176.gccxx21782184
(0.3%)
21612173
(0.6%)
21822143
(-1.8%)
-219221992158
(-1.9%)
181.mcf11491150
(0.1%)
11531149
(-0.3%)
11521148
(-0.3%)
14981500
(0.1%)
-150115061505
(-0.1%)
186.crafty18921877
(-0.8%)
19031921
(0.9%)
19521945
(-0.4%)
19351939
(0.2%)
-201120111992
(-0.9%)
197.parser17331257
(-27.5%)
17731275
(-28.1%)
17541253
(-28.6%)
17661267
(-28.3%)
-125617641251
(-29.1%)
252.eon22162622
(18.3%)
24632410
(-2.2%)
29732901
(-2.4%)
32203124
(-3.0%)
-317631773133
(-1.4%)
253.perlbmk21052104
(0.0%)
20932121
(1.3%)
21232148
(1.2%)
21422132
(-0.5%)
-220921372250
(5.3%)
254.gap18581869
(0.6%)
18891910
(1.1%)
19601999
(2.0%)
19741968
(-0.3%)
-199019901952
(-1.9%)
255.vortex28752799
(-2.6%)
28232829
(0.2%)
27972719
(-2.8%)
28562881
(0.9%)
-279728352902
(2.4%)
256.bzip214801514
(2.3%)
14621460
(-0.1%)
14311437
(0.4%)
14331430
(-0.2%)
-144214511445
(-0.4%)
300.twolf19341777
(-8.1%)
19401939
(-0.1%)
19581950
(-0.4%)
19591962
(0.2%)
-194419471953
(0.3%)
SPECint_base200018141761
(-2.9%)
18371787
(-2.7%)
18791823
(-3.0%)
19431879
(-3.3%)
-189419501893
(-2.9%)
 
168.wupwise21212131
(0.5%)
21662200
(1.6%)
21282174
(2.2%)
24562085
(-15.1%)
-219723852366
(-0.8%)
171.swim14481448
(0.0%)
21301944
(-8.7%)
21362110
(-1.2%)
21382110
(-1.3%)
-211821342111
(-1.1%)
172.mgrid12311244
(1.1%)
13301471
(10.6%)
14321463
(2.2%)
14581554
(6.6%)
-148614181566
(10.4%)
173.applu12301251
(1.7%)
12241243
(1.6%)
12051196
(-0.7%)
15301498
(-2.1%)
-153015381513
(-1.6%)
177.mesa15691587
(1.1%)
18931939
(2.4%)
20752046
(-1.4%)
20722075
(0.1%)
-201820772046
(-1.5%)
178.galgel20802056
(-1.2%)
24372459
(0.9%)
24952464
(-1.2%)
24452928
(19.8%)
-298024752915
(17.8%)
179.art17981804
(0.3%)
17851811
(1.5%)
18441839
(-0.3%)
18521847
(-0.3%)
-183926862910
(8.3%)
183.equake16571680
(1.4%)
16781669
(-0.5%)
16851680
(-0.3%)
16741671
(-0.2%)
-169316791788
(6.5%)
187.facerec18621722
(-7.5%)
18962024
(6.8%)
19022030
(6.7%)
19552036
(4.1%)
-198919632001
(1.9%)
188.ammp13901331
(-4.2%)
13331298
(-2.6%)
13191299
(-1.5%)
12761277
(0.1%)
-128512981301
(0.2%)
189.lucas16151624
(0.6%)
15701570
(0.0%)
17271734
(0.4%)
17291724
(-0.3%)
-172217301723
(-0.4%)
191.fma3d15251537
(0.8%)
14621483
(1.4%)
15661564
(-0.1%)
15931607
(0.9%)
-157016141630
(1.0%)
200.sixtrack779778
(-0.1%)
781791
(1.3%)
757779
(2.9%)
750779
(3.9%)
-820748793
(6.0%)
301.apsi14931456
(2.5%)
14751484
(0.6%)
14841492
(0.5%)
15191471
(-3.2%)
-147415101464
(-3.0%)
SPECfp_base200015151506
(-0.6%)
15961613
(1.1%)
16331642
(0.6%)
16811693
(0.7%)
-169817251776
(3.0%)

Неоптимизированный код: в целочисленных тестах и на этом процессоре весьма заметно отставание 197.parser (27.3% — аналогичную величину мы получили на Pentium M), а также 300.twolf (13.3%), которое в некоторой степени компенсируется выигрышем в задачах 252.eon (9.3%) и 254.gap (10.2%). Общая оценка SPECint_base2000 уступает предыдущей версии компилятора примерно на 3%, что вновь весьма похоже на результаты тестов Pentium M. Тесты с плавающей точкой вновь показывают результат, близкий к предыдущей версии, который и здесь достигается не равенством скорости исполнения отдельных подтестов, а их различиями как в большую, так и в меньшую стороны, компенсирующими друг друга. В результате общий результат SPECfp_base2000 уступает всего 0.6% коду, откомпилированному ICC/IFC 8.1.

Оптимизированные варианты целочисленных тестов не вносят заметных отличий в картину, полученную на других процессорах. А именно, заметное отставание 197.parser (27-28%) сохраняется, заметный же выигрыш в отдельных подтестах не наблюдается вовсе (в порядке исключения, следует отметить задачу 253.perlbmk в варианте -QxP, отличающуюся 5.3% ростом производительности). Отставание в 197.parser обуславливает примерно 3% снижение общей оценки SPECint_base2000 во всех случаях. Что касается абсолютных величин производительности, они возрастают в ряду -QxK < -QxW < -QxN < -QxP < -QxB, то есть лучшим (но совсем ненамного, и то лишь в некоторых тестах и общей оценке) вариантом оптимизации оказывается «заточка» кода под ядро Banias. Собственно, такой результат нельзя назвать из ряда вон выходящим, учитывая родство микроархитектуры AMD K8 с Intel Pentium III/Pentium M, а не Pentium 4 (NetBurst).

Переходим к оптимизированным вариантам кода SPECfp. Как и с процессорами Intel, на Athlon 64 FX-57 во всех случаях наблюдается прирост производительности при переходе к новой версии компилятора. Относительная величина выигрыша различна (зависит от типа оптимизации), различны и, скажем так, способы ее достижения. Так, в SSE-варианте (-QxK) заметно падение в 171.swim на 8.7% (заметим, что на Pentium 4 в этой задаче наоборот наблюдался выигрыш) при увеличении скорости 172.mgrid на 10.6% и 187.facerec на 6.8%, общий прирост SPECfp_base2000 составляет 1.1%. В «старом» варианте SSE2 для ядра Willamette (-QxW, который, заметим, работоспособен на AMD K8 и без «доработки») явное лидерство сохраняется лишь в задаче 187.facerec (6.7%), общий выигрыш — всего 0.6%. «Новый» вариант SSE2 для ядра Northwood отличается не большим возрастанием SPECfp_base2000 (0.7%), но заметен различный разброс величин в отдельных подтестах (-15.1%(!) в 168.wupwise, +6.6% в 172.mgrid и +19.8% в 178.galgel). Наконец, лучший вариант оптимизации под SSE3 (ядро Prescott, -QxP) характеризуется практически полным отсутствием падения производительности (следует упомянуть разве что 3% снижение в 301.aspi) при значительном росте скорости целого ряда задач (172.mgrid на 10.4%, 178.galgel на 17.8%, 179.art на 8.3%, 183.equake на 6.5%). В результате, общая оценка SPECfp_base2000 на целых 3% выше по сравнению с предыдущей версией. Что касается эффективности кода, как мы уже отметили, она наиболее высока при использовании SSE3. Вслед за ним располагается SSE2-вариант, рассчитанный на ядро Banias (-QxB), что вновь не имеет противоречий с представлениями о микроархитектуре AMD K8, далее располагаются -QxN, -QxW и -QxK.

Выводы

Новые компиляторы Intel C++/Fortran Compiler 9.0 в «типовом» варианте компиляции кода (если таковым считать компиляцию с профилированием) демонстрируют неоднозначную картину. Результирующий целочисленный код по скорости в целом несколько (на 3-5%) уступает коду, полученному с предыдущей версией компиляторов 8.1. Значимое падение производительности наблюдается лишь в одной задаче, зато весьма весомое — от 27 до 34% в зависимости от процессора. И хорошо, если пользовательский код не окажется подобным этой задаче :).

Тем не менее, в плане вычислений с вещественными числами (где используются инструкции SSE, SSE2, SSE3) новая версия компиляторов показывает некоторое преимущество над предыдущей — правда, весьма незначительное (от 0 до 3%). Сохраняется и адекватность использования ключей оптимизации под конкретную микроархитектуру процессора (-QxP для Pentium 4/Prescott, -QxB для Pentium M/Dothan, для процессоров класса AMD K8 можно рекомендовать поэкспериментировать с ключами -QxB и -QxP).

Кстати, несколько слов о процессорах AMD. Результаты проведенного исследования показывают, что обе версии ICC/IFC — 8.1 и 9.0 — выдают на выходе код, обладающий очень хорошей (а в ряде случаев — и лучшей) производительностью на процессорах конкурента… если только его немного «исправить» :), или же «исправить» библиотеки компилятора. Было бы просто замечательно, если бы корпорация Intel, производитель процессоров и компиляторов, заменила бы нынешний вариант проверки типа процессора на более разумный — наподобие того, который использовали мы.

Такая модификация оказалась бы выгодна, прежде всего, для конечных пользователей — в этом случае, даже при использовании разработчиком ПО «автоматических» вариантов оптимизации вида -Qax*, при исполнении приложения будет выбран наиболее оптимизированный вариант кода, причем в зависимости только от наличия необходимых расширенных наборов инструкций, а не изготовителя процессора. Отметим, что один из пунктов обвинения Intel со стороны AMD заключался как раз в том, что при исполнении «автоматического» варианта кода процессоры AMD могут сильно уступать процессорам конкурента, несмотря на присутствие в них необходимых расширений.

Не менее благоприятной она оказалась бы и для разработчиков и тестировщиков ПО — отпала бы необходимость использования разных компиляторов для разных процессоров, или в «привязке» к процессорам конкретного производителя при разработке и отладке приложений.

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




26 августа 2005 Г.