В середине июня компания 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.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | |
| 164.gzip | 1150 | 1130 (-1.7%) | 1253 | 1239 (-1.1%) | 1255 | 1248 (-0.6%) | 1265 | 1251 (-1.1%) | - | 1247 | 1267 | 1241 (-2.1%) |
| 175.vpr | x | x | 1207 | 1201 (-0.5%) | 1290 | 1283 (-0.5%) | 1288 | 1272 (-1.2%) | - | 1255 | 1286 | 1270 (-1.2%) |
| 176.gcc | x | x | 2142 | 2119 (-1.1%) | 2132 | 2122 (-0.5%) | 2146 | 2125 (-1.0%) | - | 2116 | 2155 | 2116 (-1.8%) |
| 181.mcf | 1595 | 1594 (-0.1%) | 1599 | 1599 (0.0%) | 1598 | 1600 (0.1%) | 2125 | 2125 (0.0%) | - | 2113 | 2131 | 2115 (-0.8%) |
| 186.crafty | 1251 | 1260 (0.7%) | 1272 | 1285 (1.0%) | 1371 | 1398 (2.0%) | 1375 | 1406 (2.3%) | - | 1387 | 1387 | 1389 (0.1%) |
| 197.parser | 1553 | 1030 (-33.7%) | 1562 | 1031 (-34.0%) | 1562 | 1026 (-34.3%) | 1560 | 1025 (-34.3%) | - | 1019 | 1560 | 1031 (-33.9%) |
| 252.eon | 1640 | 1762 (7.4%) | 1795 | 1836 (2.3%) | 2188 | 2153 (-1.6%) | 2391 | 2360 (-1.3%) | - | 2101 | 2359 | 2320 (-1.7%) |
| 253.perlbmk | 1997 | 2021 (1.2%) | 1954 | 2015 (3.1%) | 1923 | 2012 (4.6%) | 1940 | 1991 (2.6%) | - | 2018 | 1947 | 2006 (3.0%) |
| 254.gap | 2033 | 2110 (3.8%) | 1936 | 1990 (2.8%) | 2019 | 2035 (0.8%) | 2022 | 2061 (1.9%) | - | 2029 | 2032 | 2049 (0.8%) |
| 255.vortex | 2876 | 2941 (2.3%) | 2871 | 2971 (3.5%) | 2869 | 2970 (3.5%) | 2854 | 2970 (4.1%) | - | 2852 | 2833 | 2948 (4.1%) |
| 256.bzip2 | 1423 | 1428 (0.4%) | 1390 | 1399 (0.6%) | 1378 | 1372 (-0.4%) | 1360 | 1348 (-0.9%) | - | 1354 | 1372 | 1415 (3.1%) |
| 300.twolf | 1867 | 1526 (-18.3%) | 1840 | 1880 (2.2%) | 1859 | 1898 (2.1%) | 1865 | 1910 (2.4%) | - | 1879 | 1869 | 1908 (2.1%) |
| SPECint_base2000 | 1682 | 1604 (-4.6%) | 1682 | 1642 (-2.4%) | 1734 | 1687 (-2.7%) | 1790 | 1739 (-2.8%) | - | 1708 | 1792 | 1739 (-3.0%) |
| 168.wupwise | 1882 | 1843 (-2.1%) | 2031 | 2074 (2.1%) | 2235 | 2304 (3.1%) | 2198 | 1735 (-21.1%) | - | 1762 | 2860 | 2914 (1.9%) |
| 171.swim | 2089 | 2088 (0.0%) | 2362 | 2544 (7.7%) | 2524 | 2596 (2.9%) | 2525 | 2595 (2.8%) | - | 2553 | 2526 | 2595 (2.7%) |
| 172.mgrid | 1022 | 1023 (0.1%) | 1237 | 1216 (-1.7%) | 1518 | 1511 (-0.5%) | 1674 | 1661 (-0.8%) | - | 1306 | 1675 | 1661 (-0.8%) |
| 173.applu | 1419 | 1438 (1.3%) | 1404 | 1414 (0.7%) | 1481 | 1472 (-0.6%) | 1655 | 1670 (0.9%) | - | 1555 | 1638 | 1691 (3.2%) |
| 177.mesa | 1399 | 1371 (-2.0%) | 1496 | 1476 (-1.3%) | 1666 | 1669 (0.2%) | 1662 | 1668 (0.4%) | - | 1574 | 1659 | 1653 (-0.4%) |
| 178.galgel | 1445 | 1440 (-0.3%) | 3036 | 3119 (2.7%) | 3581 | 3637 (1.6%) | 3564 | 3866 (8.5%) | - | 3626 | 3603 | 3889 (7.9%) |
| 179.art | 2716 | 2356 (-13.3%) | 2370 | 2393 (1.0%) | 2918 | 2613 (-10.5%) | 2987 | 2655 (-11.1%) | - | 2524 | 4648 | 4597 (-1.1%) |
| 183.equake | 2074 | 2105 (1.5%) | 2143 | 2118 (-1.2%) | 2155 | 2154 (0.0%) | 2158 | 2148 (-0.5%) | - | 2092 | 2156 | 2420 (12.2%) |
| 187.facerec | 1736 | 1773 (2.1%) | 2035 | 2148 (5.6%) | 2049 | 2151 (5.0%) | 2037 | 2165 (6.3%) | - | 2114 | 2075 | 2179 (5.0%) |
| 188.ammp | 1305 | 1226 (-6.1%) | 1240 | 1213 (-2.2%) | 1365 | 1345 (-1.5%) | 1371 | 1346 (-1.8%) | - | 1210 | 1369 | 1346 (-1.7%) |
| 189.lucas | 2109 | 2101 (-0.4%) | 2007 | 2025 (0.9%) | 2285 | 2320 (1.5%) | 2279 | 2331 (2.3%) | - | 1984 | 2302 | 2306 (0.2%) |
| 191.fma3d | 1316 | 1342 (2.0%) | 1291 | 1342 (4.0%) | 1600 | 1648 (3.0%) | 1581 | 1683 (6.5%) | - | 1371 | 1606 | 1646 (2.5%) |
| 200.sixtrack | 604 | 606 (0.3%) | 597 | 605 (1.3%) | 678 | 754 (11.2%) | 679 | 746 (9.9%) | - | 621 | 683 | 748 (9.5%) |
| 301.apsi | 1309 | 1277 (-2.4%) | 1317 | 1301 (-1.2%) | 1386 | 1370 (-1.2%) | 1408 | 1357 (-3.6%) | - | 1300 | 1410 | 1357 (-3.8%) |
| SPECfp_base2000 | 1511 | 1489 (-1.5%) | 1636 | 1657 (1.3%) | 1826 | 1842 (0.9%) | 1854 | 1845 (-0.5%) | - | 1690 | 1956 | 2007 (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.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | |
| 164.gzip | 1143 | 1091 (-4.5%) | 1248 | 1245 (-0.2%) | 1236 | 1238 (0.2%) | 1247 | 1246 (-0.1%) | - | 1251 |
| 175.vpr | x | x | 1321 | 1316 (-0.4%) | 1367 | 1381 (1.0%) | 1364 | 1377 (1.0%) | - | 1361 |
| 176.gcc | x | x | 1822 | 1805 (-0.9%) | 1805 | 1803 (-0.1%) | 1825 | 1806 (-1.0%) | - | 1814 |
| 181.mcf | 1042 | 1059 (1.6%) | 1054 | 1052 (-0.2%) | 1051 | 1047 (-0.4%) | 1504 | 1507 (0.2%) | - | 1507 |
| 186.crafty | 1320 | 1303 (-1.3%) | 1312 | 1313 (0.1%) | 1455 | 1460 (0.3%) | 1455 | 1456 (0.1%) | - | 1631 |
| 197.parser | 1381 | 1004 (-27.3%) | 1392 | 1002 (-28.0%) | 1392 | 990 (-28.9%) | 1388 | 1008 (-27.4%) | - | 1001 |
| 252.eon | 1589 | 1736 (9.3%) | 1688 | 1668 (-1.2%) | 1922 | 1930 (0.4%) | 2096 | 2066 (-1.4%) | - | 2127 |
| 253.perlbmk | 1724 | 1716 (-0.5%) | 1736 | 1755 (1.1%) | 1750 | 1775 (1.4%) | 1752 | 1760 (0.5%) | - | 1811 |
| 254.gap | 1163 | 1282 (10.2%) | 1151 | 1168 (1.5%) | 1280 | 1302 (1.7%) | 1282 | 1298 (1.2%) | - | 1337 |
| 255.vortex | 2456 | 2484 (1.1%) | 2492 | 2497 (0.2%) | 2466 | 2492 (1.1%) | 2491 | 2488 (-0.1%) | - | 2482 |
| 256.bzip2 | 1225 | 1238 (1.1%) | 1156 | 1178 (1.9%) | 1196 | 1176 (-1.7%) | 1192 | 1178 (-1.2%) | - | 1205 |
| 300.twolf | 2102 | 1823 (-13.3%) | 2111 | 2149 (1.8%) | 2223 | 2252 (1.3%) | 2220 | 2256 (1.6%) | - | 2241 |
| SPECint_base2000 | 1459 | 1416 (-2.9%) | 1489 | 1453 (-2.4%) | 1544 | 1507 (-2.4%) | 1605 | 1564 (-2.6%) | - | 1591 |
| 168.wupwise | 1249 | 1264 (1.2%) | 1327 | 1356 (2.2%) | 1133 | 1145 (1.1%) | 1149 | 1045 (-9.1%) | - | 1285 |
| 171.swim | 713 | 722 (1.3%) | 854 | 782 (-8.4%) | 841 | 822 (-2.3%) | 845 | 821 (-2.8%) | - | 821 |
| 172.mgrid | 777 | 786 (1.2%) | 835 | 839 (0.5%) | 817 | 829 (1.5%) | 818 | 820 (0.2%) | - | 842 |
| 173.applu | 612 | 617 (0.8%) | 631 | 638 (1.1%) | 611 | 608 (-0.5%) | 701 | 703 (0.3%) | - | 729 |
| 177.mesa | 898 | 906 (0.9%) | 1379 | 1506 (9.2%) | 1578 | 1570 (-0.5%) | 1579 | 1552 (-1.7%) | - | 1651 |
| 178.galgel | 1753 | 1694 (-3.4%) | 2499 | 2503 (0.2%) | 2224 | 2237 (0.6%) | 2218 | 2428 (9.5%) | - | 2803 |
| 179.art | 2600 | 2495 (-4.0%) | 2388 | 2360 (-1.2%) | 2472 | 2437 (-1.4%) | 2645 | 2575 (-2.6%) | - | 2634 |
| 183.equake | 888 | 906 (2.0%) | 905 | 901 (-0.4%) | 898 | 898 (0.0%) | 900 | 899 (-0.1%) | - | 900 |
| 187.facerec | 1165 | 1156 (-0.8%) | 1244 | 1274 (2.4%) | 1237 | 1275 (3.1%) | 1252 | 1273 (1.7%) | - | 1268 |
| 188.ammp | 1019 | 980 (-3.8%) | 983 | 968 (-1.5%) | 922 | 905 (-1.8%) | 904 | 891 (-1.4%) | - | 963 |
| 189.lucas | 799 | 809 (1.3%) | 793 | 791 (-0.3%) | 891 | 899 (0.9%) | 895 | 898 (0.3%) | - | 897 |
| 191.fma3d | 808 | 821 (1.6%) | 801 | 812 (1.4%) | 829 | 840 (1.3%) | 839 | 853 (1.7%) | - | 845 |
| 200.sixtrack | 542 | 540 (-0.4%) | 533 | 513 (-3.8%) | 464 | 474 (2.2%) | 452 | 475 (5.1%) | - | 528 |
| 301.apsi | 916 | 903 (-1.4%) | 916 | 913 (-0.3%) | 851 | 853 (0.2%) | 856 | 846 (-1.2%) | - | 902 |
| SPECfp_base2000 | 963 | 960 (-0.3%) | 1038 | 1038 (0.0%) | 1015 | 1018 (0.3%) | 1031 | 1030 (-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.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | ic8.1 | ic9.0 | |
| 164.gzip | 1437 | 1363 (-5.1%) | 1568 | 1571 (0.2%) | 1546 | 1546 (0.0%) | 1566 | 1540 (-1.7%) | - | 1584 | 1574 | 1558 (-1.0%) |
| 175.vpr | x | x | 1429 | 1406 (-1.6%) | 1515 | 1510 (-0.3%) | 1516 | 1503 (-0.9%) | - | 1483 | 1514 | 1486 (-1.8%) |
| 176.gcc | x | x | 2178 | 2184 (0.3%) | 2161 | 2173 (0.6%) | 2182 | 2143 (-1.8%) | - | 2192 | 2199 | 2158 (-1.9%) |
| 181.mcf | 1149 | 1150 (0.1%) | 1153 | 1149 (-0.3%) | 1152 | 1148 (-0.3%) | 1498 | 1500 (0.1%) | - | 1501 | 1506 | 1505 (-0.1%) |
| 186.crafty | 1892 | 1877 (-0.8%) | 1903 | 1921 (0.9%) | 1952 | 1945 (-0.4%) | 1935 | 1939 (0.2%) | - | 2011 | 2011 | 1992 (-0.9%) |
| 197.parser | 1733 | 1257 (-27.5%) | 1773 | 1275 (-28.1%) | 1754 | 1253 (-28.6%) | 1766 | 1267 (-28.3%) | - | 1256 | 1764 | 1251 (-29.1%) |
| 252.eon | 2216 | 2622 (18.3%) | 2463 | 2410 (-2.2%) | 2973 | 2901 (-2.4%) | 3220 | 3124 (-3.0%) | - | 3176 | 3177 | 3133 (-1.4%) |
| 253.perlbmk | 2105 | 2104 (0.0%) | 2093 | 2121 (1.3%) | 2123 | 2148 (1.2%) | 2142 | 2132 (-0.5%) | - | 2209 | 2137 | 2250 (5.3%) |
| 254.gap | 1858 | 1869 (0.6%) | 1889 | 1910 (1.1%) | 1960 | 1999 (2.0%) | 1974 | 1968 (-0.3%) | - | 1990 | 1990 | 1952 (-1.9%) |
| 255.vortex | 2875 | 2799 (-2.6%) | 2823 | 2829 (0.2%) | 2797 | 2719 (-2.8%) | 2856 | 2881 (0.9%) | - | 2797 | 2835 | 2902 (2.4%) |
| 256.bzip2 | 1480 | 1514 (2.3%) | 1462 | 1460 (-0.1%) | 1431 | 1437 (0.4%) | 1433 | 1430 (-0.2%) | - | 1442 | 1451 | 1445 (-0.4%) |
| 300.twolf | 1934 | 1777 (-8.1%) | 1940 | 1939 (-0.1%) | 1958 | 1950 (-0.4%) | 1959 | 1962 (0.2%) | - | 1944 | 1947 | 1953 (0.3%) |
| SPECint_base2000 | 1814 | 1761 (-2.9%) | 1837 | 1787 (-2.7%) | 1879 | 1823 (-3.0%) | 1943 | 1879 (-3.3%) | - | 1894 | 1950 | 1893 (-2.9%) |
| 168.wupwise | 2121 | 2131 (0.5%) | 2166 | 2200 (1.6%) | 2128 | 2174 (2.2%) | 2456 | 2085 (-15.1%) | - | 2197 | 2385 | 2366 (-0.8%) |
| 171.swim | 1448 | 1448 (0.0%) | 2130 | 1944 (-8.7%) | 2136 | 2110 (-1.2%) | 2138 | 2110 (-1.3%) | - | 2118 | 2134 | 2111 (-1.1%) |
| 172.mgrid | 1231 | 1244 (1.1%) | 1330 | 1471 (10.6%) | 1432 | 1463 (2.2%) | 1458 | 1554 (6.6%) | - | 1486 | 1418 | 1566 (10.4%) |
| 173.applu | 1230 | 1251 (1.7%) | 1224 | 1243 (1.6%) | 1205 | 1196 (-0.7%) | 1530 | 1498 (-2.1%) | - | 1530 | 1538 | 1513 (-1.6%) |
| 177.mesa | 1569 | 1587 (1.1%) | 1893 | 1939 (2.4%) | 2075 | 2046 (-1.4%) | 2072 | 2075 (0.1%) | - | 2018 | 2077 | 2046 (-1.5%) |
| 178.galgel | 2080 | 2056 (-1.2%) | 2437 | 2459 (0.9%) | 2495 | 2464 (-1.2%) | 2445 | 2928 (19.8%) | - | 2980 | 2475 | 2915 (17.8%) |
| 179.art | 1798 | 1804 (0.3%) | 1785 | 1811 (1.5%) | 1844 | 1839 (-0.3%) | 1852 | 1847 (-0.3%) | - | 1839 | 2686 | 2910 (8.3%) |
| 183.equake | 1657 | 1680 (1.4%) | 1678 | 1669 (-0.5%) | 1685 | 1680 (-0.3%) | 1674 | 1671 (-0.2%) | - | 1693 | 1679 | 1788 (6.5%) |
| 187.facerec | 1862 | 1722 (-7.5%) | 1896 | 2024 (6.8%) | 1902 | 2030 (6.7%) | 1955 | 2036 (4.1%) | - | 1989 | 1963 | 2001 (1.9%) |
| 188.ammp | 1390 | 1331 (-4.2%) | 1333 | 1298 (-2.6%) | 1319 | 1299 (-1.5%) | 1276 | 1277 (0.1%) | - | 1285 | 1298 | 1301 (0.2%) |
| 189.lucas | 1615 | 1624 (0.6%) | 1570 | 1570 (0.0%) | 1727 | 1734 (0.4%) | 1729 | 1724 (-0.3%) | - | 1722 | 1730 | 1723 (-0.4%) |
| 191.fma3d | 1525 | 1537 (0.8%) | 1462 | 1483 (1.4%) | 1566 | 1564 (-0.1%) | 1593 | 1607 (0.9%) | - | 1570 | 1614 | 1630 (1.0%) |
| 200.sixtrack | 779 | 778 (-0.1%) | 781 | 791 (1.3%) | 757 | 779 (2.9%) | 750 | 779 (3.9%) | - | 820 | 748 | 793 (6.0%) |
| 301.apsi | 1493 | 1456 (2.5%) | 1475 | 1484 (0.6%) | 1484 | 1492 (0.5%) | 1519 | 1471 (-3.2%) | - | 1474 | 1510 | 1464 (-3.0%) |
| SPECfp_base2000 | 1515 | 1506 (-0.6%) | 1596 | 1613 (1.1%) | 1633 | 1642 (0.6%) | 1681 | 1693 (0.7%) | - | 1698 | 1725 | 1776 (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 — ибо начисто отпала бы необходимость в разработке собственного компилятора, которая вот уже долгое время находится в состоянии неопределенности :).