Восьма версія компіляторів Intel. Спільне використання модулів на Фортрані та Сі

Наприкінці 2003 року корпорація Intel представила версію 8.0 своєї колекції компіляторів. Нові компілятори покликані підвищити продуктивність програм, що працюють на серверах, настільних ПК та мобільних системах(Ноутбуки, мобільні телефони та кишенькові комп'ютери) на базі процесорів Intel. Приємно відзначити, що цей продукт створений за активної участі співробітників Центру Intel з нижнього міста Intel з розробки ПЗ і фахівців Intel з Сарова.

Нова серія включає компілятори Intel для мов C++ і Fortran для Windows і Linux, а також компілятори Intel для мови C++ для Windows CE .NET. Компілятори орієнтовані системи на базі наступних процесорів Intel: Intel Itanium 2, Intel Xeon, Intel Pentium 4, процесорів з архітектурою Intel Personal Internet Client Architecture для мобільних телефонівта кишенькових ПК та процесора Intel Pentium M для мобільних ПК (компонент технології Intel Centrino для мобільних ПК).

У компіляторі Intel Visual Fortran для Windows реалізовані технології компіляції нового покоління для високопродуктивних обчислювальних рішень. Він поєднує в собі функціональність мови Compaq Visual Fortran (CVF) та підвищення продуктивності, що стало можливим завдяки технологіям оптимізації компіляції та генерації коду корпорації Intel, та спрощує завдання перенесення вихідного коду, Розроблений за допомогою CVF, в середу Intel Visual Fortran. У цьому компіляторі функції CVF вперше реалізовані як для 32-розрядних систем Intel, так і систем на базі процесорів сімейства Intel Itanium, що працюють в середовищі Windows. Крім того, цей компілятор дозволяє реалізувати мовні функції CVF у системах під управлінням ОС Linux на базі 32-розрядних процесорів Intel та процесорів сімейства Intel Itanium. В 2004 планується випустити розширену версію цього компілятора - компілятор Intel Visual Fortran Compiler Professional Edition для ОС Windows, до складу якої буде включена бібліотека IMSL Fortran 5.0 Library, розроблена компанією Visual Numerics, Inc.


"Нові компілятори підтримують також майбутні процесори Intel, відомі під кодовою назвою Prescott, у яких передбачені нові команди для підвищення продуктивності графіки та відео, а також інші засоби збільшення продуктивності. Вони також підтримують нову технологію Mobile MMX(tm), що аналогічно підвищує продуктивність графічних, звукових та відеододатків для мобільних телефонів та кишенькових ПК, - зазначив співдиректор Центру Intel з розробки ПЗ у Нижньому Новгороді Олексій Одиноков. - Ці компілятори надають розробникам додатків єдиний комплекс інструментальних засобів для побудови нових додатків бездротових мережз урахуванням архітектури Intel. Нові компілятори Intel також підтримують технологію Hyper-Threading корпорації Intel та галузеву специфікацію OpenMP 2.0, яка визначає використання директив високого рівня для управління потоками інструкцій у додатках.

Серед нових інструментів, включених до компіляторів - засоби Intel Code Coverage та Intel Test Prioritization. Водночас ці засоби дозволяють прискорити розробку додатків та підвищити їх якість за рахунок покращення процесу тестування. програмного забезпечення.

Засіб Code Coverage під час тестування програми надає повні відомості про використання логіки програми та про розташування ділянок у вихідному коді програми. У випадку, якщо додаток вносяться зміни або якщо цей тест не дозволяє перевірити частину програми, яка цікавить розробника, засіб Test Prioritization дозволяє перевірити роботу вибраної ділянки програмного коду.

Нові компілятори Intel випускаються у різних комплектаціях вартістю від 399 до 1499 доларів. Їх можна придбати вже сьогодні у корпорації Intel або у реселерів по всьому світу, список яких розташований на сайті http://www.intel.com/software/products/reseller.htm#Russia.

Підтримка процесорів Prescott

Підтримка процесора Intel Pentium 4 (Prescott) у восьмій версії компілятора полягає в наступному:

1. Підтримка команд SSE3 (або PNI, Prescott New Instructions). Тут варто виділити три способи:

а. Асемблерні вставки (Inline assembly). Наприклад, компілятор розпізнає наступне використання команди з набору SSE3 _asm(addsubpd xmm0, xmm1). Таким чином, користувачі, зацікавлені в низькорівневій оптимізації, можуть отримати прямий доступ до асемблерних команд.

б. У C/C++ компіляторі нові інструкції доступні з більш високого рівня, ніж використання асемблерних вставок. А саме, за допомогою вбудованих функцій (intrinsic functions):

Вбудовані функції

Вбудована функціяГенерована команда
_mm_addsub_psAddsubps
_mm_hadd_psHaddps
_mm_hsub_psMsubps
_mm_moveldup_psMovsldup
_mm_movehdup_psMovshdup
_mm_addsub_pdAddsubpd
_mm_hadd_pdHaddpd
_mm_hsub_pdHsubpd
_mm_loaddup_pdmovddup xmm, m64
_mm_movedup_pdmovddup reg, reg
_mm_lddqu_si128Lddqu

У таблиці показані вбудовані функції та відповідні асемблерні команди з набору SSE3. Така ж підтримка існує і для команд з наборів MMX SSE2. Це дозволяє програмісту здійснювати низькорівневу оптимізацію коду, не вдаючись до програмування на асемблері: компілятор сам дбає про відображення (mapping"е) вбудованих функцій на відповідні команди процесора і оптимальне використання регістрів. Програміст може сконцентруватися на створенні алгоритму, що ефективно використовує нові набір.

в. Автоматична генерація нових команд компілятором. Попередні два способи передбачають використання програмістом нових команд. Але компілятор здатний також (при використанні відповідних опцій - див. секцію 3 нижче) автоматично генерувати нові команди набору SSE3 для програмного коду мовами С/C++ і Fortran. Наприклад, оптимізовану команду невирівняного завантаження (lddqu), використання якої дозволяє отримати виграш за продуктивністю до 40% (наприклад, завдання відео- і аудіокодування). Інші команди з набору SSE3 дозволяють отримати суттєве прискорення у задачах 3D графіки або розрахункових задачах з використанням комплексних чисел. Наприклад, графік у секції 3.1 нижче показує, що додаток 168.wupwise з набору SPEC CPU2000 FP прискорення, отримане від автоматичної генерації команд SSE3 становило ~25%. Продуктивність цієї програми істотно залежить від швидкості арифметики комплексних чисел.

2. Використання мікроархітектурних переваг процесора Prescott. При генерації коду компілятор враховує мікроархітектурні зміни нового процесора. Наприклад, виконання деяких операцій (таких як цілісні зрушення, множення цілих чисел або перетворення чисел між різними форматами з плаваючою точкою в SSE2) прискорилося на новому процесорі по відношенню до попередніх версій (скажімо, цілісний зсув займає тепер один процесорний такт проти чотирьох для попередньої версії процесора Intel Pentium 4). Більш інтенсивне використання таких команд дозволяє отримати значне прискорення роботи додатків.
Іншим прикладом мікроархітектурних змін є покращений механізм store forwarding (швидкого завантаження даних, що зберігаються раніше в пам'яті); реальне збереження відбувається навіть не в кеш-пам'ять, а в деякий проміжний буфер збереження, що дозволяє здійснити дуже швидкий доступ до даних. Така особливість архітектури дає можливість, наприклад, здійснити агресивнішу автоматичну векторизацію програмного коду.
Компілятор також враховує збільшений обсяг кеш-пам'яті першого та другого рівня.

3. Покращена підтримка технології Hyper-Threading. Цей пункт цілком може бути віднесений до попереднього - мікроархітектурних змін та їх використання у компіляторі. Наприклад, бібліотека часу виконання, у якій реалізується підтримка галузевої специфікації OpenMP, була оптимізована до виконання новому процесорі.

Продуктивність

Використання компіляторів є простим і ефективним способом скористатися перевагами процесорних архітектур Intel. Нижче умовно (дуже) виділено два способи використання компіляторів: а) перекомпіляція програм з можливою зміною налаштувань компілятора; програмних засобів(наприклад, профільників).


1.1 Оптимізація програм за допомогою перекомпіляції та зміни настройок компілятора


Найчастіше першим кроком у переході на новий компілятор, що оптимізує, є його використання з налаштуваннями за замовчуванням. Наступний логічний крок – використання опцій для більш агресивної оптимізації. На рисунках 1, 2, 3 і 4 показаний ефект від переходу на інтелівський компілятор версії 8.0 порівняно з використанням інших лідируючих у галузі продуктів (-O2 – налаштування компіляторів за замовчуванням, base – налаштування на максимальну продуктивність). Порівняння проводиться на 32- та 64-бітних архітектурах Intel. Як тестовий набір використовуються програми зі SPEC CPU2000.


Малюнок 1




Малюнок 2




Малюнок 3




Малюнок 4


Нижче перераховані деякі опції (далі за текстом опції наведені для сімейства ОС Windows; для сімейства ОС Linux існують опції з тією ж дією, але назва може відрізнятися; наприклад, -Od або QxK для Windows надають аналогічну дію з -O0 або -xK для Linux відповідно, докладнішу інформацію можна знайти у посібнику з використання компілятора), підтримувані компілятором Intel.


Контроль рівнів оптимізації: Опції -Od (відсутність оптимізації; застосовується для налагодження програм), -O1 ( максимальна швидкістьпри мінімізації розміру коду), -O2 (оптимізація за швидкістю виконання коду; застосовується за замовчуванням), -O3 (включає найбільш агресивні оптимізації за швидкістю виконання коду; в деяких випадках може призводити до зворотного ефекту, тобто до уповільнення; слід зазначити , що на IА-64 використання O3 веде до прискорення в більшості випадків, тоді як позитивний ефект на IA-32 менш яскраво виражений). Приклади оптимізації, що включаються по -O3: перестановка порядку вкладених циклів (loop interchange), злиття циклів (loop fusion), поділ циклу (-ів) (loop distribution; оптимізація, зворотна loop fusion), програмна передвиборка (software prefetch) даних. Причина, через яку можливе уповільнення при використанні -O3, може полягати в тому, що компілятор використовував евристичний підхід до вибору агресивної оптимізації для конкретного випадку, не маючи достатньої інформації про програму (наприклад, згенерував команди передвиборки для даних, що використовуються в циклі, вважаючи, що цикл виконується багато разів, тоді як насправді він має лише кілька ітерацій). Інтерпроцедурна оптимізація із профілювання, а також різноманітні "підказки" програміста (див. секцію 3.2) можуть допомогти у цій ситуації.

Інтерпроцедурна оптимізація: -Qip (в рамках одного файлу) та -Qipo (в рамках декількох або всіх файлів проекту). Включає такі оптимізації, як, наприклад, інлайн-підстановка коду, що часто використовується (скорочення витрат на виклик функції/процедури). Надає інформацію іншим стадіям оптимізації - наприклад, інформацію про верхню межу циклу (скажімо, якщо це константа часу компіляції, визначена в одному файлі, а використовувана в багатьох) або інформацію про вирівнювання даних у пам'яті (багато команд MMX\SSE\SSE2\SSE3 працюють швидше, якщо операнди вирівняні в пам'яті на межу 8 або 16 байт). Аналіз процедур аллокації пам'яті (реалізованих\викликаних в одному з файлів проекту) передається в ті функції\процедури, де ця пам'ять використовується (це може допомогти компілятору відмовитися від консервативного припущення, що дані не вирівняні в пам'яті належним чином, а припущення має бути консервативним при відсутності додаткової інформації). Ще одним прикладом може бути аналіз перетинів пам'яті (disambiguation, data aliasing analysis): за відсутності додаткової інформації та неможливості довести відсутність перетинів, компілятор виходить із консервативного припущення, що перетину є. Таке рішення може негативно позначитися на якості таких оптимізації, як, наприклад, автоматична векторизація на IA-32 або програмна конвеєризація (software pipelining або SWP) на IA-64. Інтерпроцедурна оптимізація може допомогти в аналізі перетинів пам'яті.

Оптимізація з профілювання: Включає три стадії 1) генерацію інструментованого коду за допомогою опції Qprof_gen. 2) отриманий код запускається на репрезентативних даних, під час роботи збирається інформація про різних характеристикахвиконання коду (наприклад, ймовірності переходу або типове значення кількості ітерацій циклу). 3) Повторна компіляція опції -Qprof_use, яка забезпечує використання компілятором інформації, зібраної на попередньому кроці. Таким чином, компілятор має можливість використовувати не лише статичні оцінки важливих характеристик програми, а й дані, отримані під час реального прогону програми. Це може допомогти при наступному виборі тих чи інших оптимізацій (наприклад, більш ефективне розташування в пам'яті різних гілок програми, ґрунтуючись на інформації про те, які гілки виконувались з якою частотою; або застосування оптимізації до циклу на основі інформації про типову кількість ітерацій у ньому) . Оптимізація з профілювання особливо корисна у випадках, коли вдається підібрати невеликий, але репрезентативний набір даних (для кроку №2), який добре ілюструє найбільш типові випадки майбутнього використання програми. У деяких предметних областяхВибір такого репрезентативного набору цілком можливий. Наприклад, оптимізація із профілювання використовується розробниками СУБД.

Оптимізації, перелічені вище ставляться до загального (generic) типу, тобто. згенерований код буде працювати на всіх різних процесорах сімейства (скажімо, у разі 32-х розрядної архітектури - на всіх перерахованих нижче процесорах: Intel Pentium-III, Pentium 4, включаючи ядро ​​Prescott, Intel Pentium M). Існують також оптимізацію під конкретний процесор.

Оптимізації, орієнтовані на конкретний процесор: -QxK (Pentium-III; використання команд набору SSE, особливостей мікроархітектури), -QxW та -QxN (Pentium 4; використання команд SSE та SSE2, особливостей мікроархітектури), -QxB (Pentium M; використання команд SSE та SSE2, особливостей мікроархітектури ), QxP (Prescott; використання команд SSE, SSE2, та SSE3, особливостей мікроархітектури). В даному випадкукод, згенерований з використанням таких опцій, може працювати на інших представниках процесорної лінійки (наприклад, -QxW код може призвести до виконання неприпустимої команди, якщо виконується на системі на базі процесора Intel Pentium-III). Або працювати не з максимальною ефективністю (наприклад, -QxB код на процесорі Pentium 4 через відмінності в мікроархітектурі). При таких опціях можливе використання бібліотек часу виконання, оптимізованих під конкретний процесор з використанням його системи команд. Для контролю того, що код виконується на цільовому процесорі, реалізований механізм диспетчеризації (cpu-dispatch): перевірка процесора під час виконання програми. У різних ситуаціях цей механізм може бути задіяний, або ні. Диспетчеризація використовується завжди, якщо застосовується варіація опцій Qax (KWNP). У цьому випадку генерується дві версії коду: оптимізована під конкретний процесор та "загальна" (generic), вибір відбувається під час виконання програми. Таким чином, за рахунок збільшення розміру коду можна досягти виконання програми на всіх процесорах лінійки та оптимального виконання на цільовому процесорі. Інший варіант полягає у використанні оптимізації коду під попереднього представника лінійки та використання цього коду на цьому та наступних процесорах. Наприклад, код QxN може виконуватися на Pentium 4 як з ядром Northwood, так і Prescott. Збільшення розміру коду не відбувається. При такому підході можна отримати хорошу, але все ж таки не оптимальну продуктивність на системі з процесором Prescott (тому що не використовується SSE3 і не враховуються відмінності в мікроархітектурі) при оптимальній продуктивності на Northwood. Для процесорів архітектури IA-64 також існують такі опції. На даний момент їх дві: -G1 (Itanium) та -G2 (Itanium 2; опція за замовчуванням).

Наведений нижче графік (рисунок 5) показує прискорення (за початок відліку прийнята одиниця - відсутність будь-якого прискорення) від використання деяких перерахованих вище оптимізації (а саме -O3 -Qipo -Qprof_use -Qx(N,P)) на процесорі Prescott порівняно за замовчуванням (-О2). Використання -QxP допомагає у деяких випадках отримати прискорення порівняно з QxN. Найбільше прискорення досягається у додатку 168.wupwise, що вже згадувалося у попередній секції (за рахунок інтенсивної оптимізації комплексної арифметики з використанням команд SSE3).


Малюнок 5


На малюнку 6 нижче показано співвідношення (у разах) швидкості роботи коду з оптимальними налаштуваннями порівняно з зовсім неоптимізованим кодом (-Od) на процесорах Pentium 4 та Itanium 2. Видно, що Itanium 2 набагато сильніше залежить від якості оптимізації. Особливо яскраво це виражено для обчислень з плаваючою точкою (FP), де відношення становить приблизно 36 разів. Обчислення з плаваючою точкою є сильною стороною архітектури IA-64, але при цьому треба ретельно підходити до використання максимально ефективних налаштувань компілятора. Отриманий виграш у продуктивності окупає трудомісткі витрати на їх пошук.


Рисунок 6. Прискорення при застосуванні найкращих опцій оптимізації SPEC CPU200


Компілятори Intel підтримують галузеву специфікацію OpenMP для створення багатопотокових програм. Підтримуються явний (опція -Qopenmp) та автоматичний (-Qparallel) режим розпаралелювання. У разі явного режиму програміст відповідальний за коректне та ефективне використання засобів стандарту OpenMP. У разі автоматичного розпаралелювання на компілятор лягає додаткове навантаження, пов'язане з аналізом програмного коду. З цієї причини в даний час автоматичне розпаралелювання ефективно працює лише на досить простих кодах.

Графік на малюнку 7 показує прискорення від використання явного розпаралелювання на інженерному (pre-production) зразку системи на базі процесора Intel Pentium 4 (Prescott) з підтримкою технології Hyper-Threading: 2.8GHz, 2GB RAM, 8K L1-Cache, 512K L2-Ca . Як набор тестів використовується SPEC OMPM2001. Цей набір орієнтується на малі та середні SMP системи, витрата пам'яті становить до двох гігабайт. Програми скомпільовані за допомогою Intel 8.0 C/C++ та Fortran c двома наборами опцій: -Qopenmp -Qipo -O3 -QxN та -Qopenmp -Qipo -O3 -QxP, з кожним з яких програми запускалися з включеною та вимкненою технологією Hyper-Threading. Значення прискорень на графіку нормалізовані на продуктивність однопотокової версії за вимкненої технології Hyper-Threading.


Рисунок 7: Програми з набору SPEC OMPM2001 на процесорі Prescott


Видно, що в 9 з 11 випадків використання явного розпаралелювання за допомогою OpenMP дає приріст продуктивності при включенні технології Hyper-Threading. В одному з програм (312.swim) спостерігається уповільнення. Це відомий факт: цей додатокхарактеризується високим ступенем залежності від пропускної спроможностіпам'яті. Так само, як і у випадку зі SPEC CPU2000, програма wupwise значно виграє від застосування оптимізації під Prescott (-QxP).


1.2 Оптимізація програм із внесенням змін у вихідний текст та використанням діагностики компілятора


У попередніх секціях ми розглядали вплив компілятора (та його налаштувань) на швидкість виконання програмного коду. У той же час, компілятори Intel представляють ширші можливості для оптимізації коду, ніж просто зміни налаштувань. Зокрема, компілятори дають можливість програмісту робити "підказки" (hints) у коді програми, які дозволяють здійснювати генерацію ефективнішого коду з погляду продуктивності. Нижче деякі приклади для мови С/C++ (для мови Fortran існують аналогічні засоби, що відрізняються лише синтаксисом).

#pragma ivdep (де ivdep означає ignore vector dependencies) застосовується перед програмними циклами, щоб повідомити компілятор, що всередині немає залежностей за даними. Ця підказка працює у тому випадку, коли компілятор (на основі аналізу) консервативно передбачає, що такі залежності можуть бути (якщо компілятор в результаті аналізу може довести, що залежність існує, то "підказка" не має жодної дії), тоді як автор коду знає що таких залежностей не може виникнути. За допомогою цієї підказки компілятор може згенерувати ефективніший код: автоматична векторизація для IA-32 (використання векторних команд з наборів MMX\SSE\SSE2\SSE3 для програмних циклів на C/C++ та Fortran; більш докладно познайомитися з цією технікою можна, наприклад, у наступному статті в Intel Technology Journal), програмна конвеєризація (SWP) для IA-64

#pragma vector always застосовується, щоб компілятор змінив рішення про неефективність векторизації циклу (як автоматичну для IA-32, так і SWP для IA-64), зроблене на основі аналізу кількісних та якісних характеристик роботи на кожній ітерації.

#pragma novector діє, зворотне #pragma vector always.

#pragma vector aligned використовується, щоб повідомити компілятор, що дані, що використовуються в циклі, вирівняні на кордон в 16 байт. Це дозволяє генерувати більш ефективний та/або компактний (через відсутність перевірок під час виконання) код.

#pragma vector unaligned діє, зворотне #pragma aligned. Про виграш у продуктивності в цьому випадку говорити складно, але можна розраховувати на більш компактний код.

#pragma distribute point використовується всередині програмного циклу, щоб компілятор міг розбити цикл (loop distribution) у цій точці на кілька дрібніших. Наприклад, подібна "підказка" може бути використана в тому випадку, коли компілятор не вдається зробити автоматичну векторизацію вихідного циклу (наприклад, через залежність за даними, яку не можна ігнорувати навіть за наявності #pragma ivdep), тоді як кожен (або частина) із знову утворених циклів може бути ефективно векторизований.

#pragma loop count (N), застосовується для того, щоб повідомити компілятору, що найбільш ймовірне значення кількості ітерацій циклу дорівнюватиме N. Ця інформація допомагає прийняти рішення про найбільш ефективну оптимізацію для цього циклу (наприклад, чи потрібно робити розгортку, чи потрібно робити SWP або автоматичну векторизацію, чи потрібно використовувати команди програмної передвиборки даних, ...)

"Підказка" _assume_aligned(p, base) застосовується для того, щоб повідомити компілятору, що область пам'яті, що асоціюється з покажчиком p, вирівняна на межу base = 2^n байт.

Це далеко не повний списокрізних "підказок" компілятору, які можуть суттєво вплинути на ефективність коду, що генерується. Може виникнути питання, як визначити, що компілятору потрібна підказка.

По-перше, можна використовувати діагностику компілятора як звітів, які він надає програмісту. Наприклад, при використанні опції -Qvec_reportN (де N змінюється від 0 до 3 і означає рівень деталізації) можна отримати звіт про автоматичну векторизацію. Програмістові буде доступна інформація про те, які цикли були векторизовані, а які – ні. У негативному випадку компілятор вказує причини, з яких векторизація не вдалася. Припустимо, що причиною стала консервативно передбачувана залежність за даними. У разі, якщо програміст впевнений, що залежності виникнути неспроможна, можливе застосування #pragma ivdep. Аналогічні (порівнюючи з Qvec_reportN для IA-32) можливості компілятора представляє на IA-64 для контролю наявності та ефективності SWP. В цілому, компілятори Intel представляють широкі можливості для діагностики оптимізації.

По-друге, інші програмні продукти (такі, наприклад, як профілювальник Intel VTune) можуть використовуватись для пошуку "вузьких місць" у коді з точки зору продуктивності. Результати аналізу можуть допомогти програмісту зробити потрібні зміни.

Можна також використовувати для аналізу асемблерний лістинг коду, що генерується компілятором.


Малюнок 8


Вище на малюнку 8 показано покроковий процесоптимізації програми за допомогою компілятора (та інших програмних продуктів) Intel мовою Fortran для архітектури IA-64. Як приклад розглядається неадіабатична регіональна схема прогнозу на 48 годин Росгідрометцентру (можна прочитати про неї, наприклад, у цій статті. У статті йдеться про час розрахунку порядку 25 хвилин, але з часу її написання відбулися значні зміни. Як точка відліку взята продуктивність коду на системі Cray-YMP Незмінений код з опціями компілятора за замовчуванням (-O2) показав приріст продуктивності в 20% на чотирипроцесорній системі на базі процесора Intel Itanium 2 900 MHz. Застосування більш агресивної оптимізації (-О3) призвело до прискорення ~2. без зміни коду в основному за рахунок SWP та передвиборки даних Аналіз за допомогою діагностики компілятора та профільника Intel VTune виявив деякі "вузькі місця", наприклад, компілятор не зробив програмну конвеєризацію кількох важливих для продуктивності циклів, повідомивши у звіті, що передбачає залежність за даними Невеликі зміни коду (директива ivdep) допомогли досягти ефекту ної конвеєризації. За допомогою профілів VTune вдалося виявити (а звіт компілятора це підтвердив), що компілятор не зробив зміни порядку вкладених циклів (loop interchange) для більш ефективного використання кеш-пам'яті. Причиною знову стали консервативні припущення про залежність за даними. Зміни були зроблені у тексті програми. У результаті вдалося досягти 4-кратного прискорення по відношенню до початкової версії. Використання явного розпаралелювання за допомогою директив стандарту OpenMP, а потім перехід на систему з процесорами вищої частоти дозволили скоротити час рахунку до показника менше 8 хвилин, що дало більш ніж 16-кратне прискорення порівняно з початковою версією.

Intel Visual Fortran

У Intel Visual Fortran 8.0 використовуються front-end (частина компілятора, що відповідає за перетворення програми з тексту мовою програмування на внутрішнє уявлення компілятора, яке багато в чому не залежить ні від мови програмування, ні від цільової машини) технології компілятора CVF та компоненти інтелівського компілятора, відповідальні за набір оптимізацій та генерацію коду.


Малюнок 9




Малюнок 10


На рисунках 9 і 10 наведено графіки порівняння продуктивності Intel Visual Fortran 8.0 с попередньою версією Intel Fortran 7.1 та з іншими популярними в галузі компіляторами цієї мови, що працюють під управлінням ОС сімейств Windows і Linux. Для порівняння використовувалися тести, вихідні тексти яких, які відповідають стандартам F77 та F90, доступні на сайті http://www.polyhedron.com/. На цьому ж сайті доступна більш детальна інформація про порівняння продуктивності компіляторів (Win32 Compiler Comparisons -> Fortran (77, 90) Execution Time Benchmarks та Linux Compiler Comparisons -> Fortran (77, 90) Execution Time Benchmarks): показано більше різних компіляторів, геометричне середнє дано у поєднанні з індивідуальними результатами кожного тесту.

Попередній номер журналу ми обговорювали продукти сімейства Intel VTune Performance Analyzer - засобів аналізу продуктивності, які користуються заслуженою популярністю у розробників додатків і дозволяють виявляти в коді додатків команди, На які витрачається занадто багато ресурсів процесора, що дає розробникам можливість виявити та усунути потенційні вузькі місця, пов'язані з подібними ділянками коду, прискоривши цим процес розробки додатків. Зазначимо, однак, що продуктивність додатків багато в чому залежить від того, наскільки ефективні компілятори, що застосовуються при їх розробці, і які особливості апаратного забезпечення вони використовують при генерації машинного коду.

Останні версії компіляторів Intel Intel C++ та Intel Fortran для ОС Windows та Linux дозволяють отримати виграш у продуктивності програм для систем на базі процесорів Intel Itanium 2, Intel Xeon та Intel Pentium 4 до 40% порівняно з існуючими компіляторами від інших виробників за рахунок використання таких особливості зазначених процесорів, як технологія Hyper-Threading.

До відмінностей, пов'язаних з оптимізацією коду даним сімейством компіляторів, слід віднести застосування стека для виконання операцій з плаваючою точкою, міжпроцедурну оптимізацію (Interprocedural Optimization, IPO), оптимізацію відповідно до профілю програми (Profile Guided Optimization, PGO), попереднє завантаження даних до (Data prefetching), яка дозволяє уникнути затримки, пов'язаної з доступом до пам'яті, підтримку характерних особливостей процесорів Intel (наприклад, розширень для потокової обробки даних Intel Streaming SIMD Extensions 2, характерних для Intel Pentium 4), автоматичне розпаралелювання виконання коду, створення програм, виконуються на кількох різних типахпроцесорів при оптимізації одного з них, засоби «пророкування» наступного коду (branch prediction), розширену підтримку роботи з потоками виконання.

Зазначимо, що компілятори Intel застосовуються у таких відомих компаніях, як Alias/Wavefront, Oracle, Fujitsu Siemens, ABAQUS, Silicon Graphics, IBM. За даними незалежного тестування, проведеного рядом компаній, продуктивність компіляторів Intel значно перевищує продуктивність компіляторів інших виробників (див., наприклад, http://intel.com/software/products/compilers/techtopics/compiler_gnu_perf.pdf).

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

Компілятори для платформи Microsoft Windows

Intel C++ Compiler 7.1 для Windows

Intel C++ Compiler 7.1 - це компілятор, випущений на початку цього року, який дозволяє досягти високого ступеня оптимізації коду для процесорів Intel Itanium, Intel Itanium 2, Intel Pentium 4 та Intel Xeon, а також для процесора Intel Pentium M, що використовує технологію Intel Centrino та призначеного для застосування у мобільних пристроях.

Зазначений компілятор повністю сумісний із засобами розробки Microsoft Visual C++ 6.0 та Microsoft Visual Studio .NET: він може бути вбудований у відповідні середовища розробки.

Цей компілятор підтримує стандарти ANSI та ISO C/C++.

Intel Fortran Compiler 7.1 для Windows

Компілятор Intel Fortran Compiler 7.1 для Windows, також випущений на початку поточного року, дозволяє створювати оптимізований код для процесорів Intel Itanium, Intel Itanium 2, Intel Pentium 4 та Intel Xeon, Intel Pentium M.

Цей компілятор повністю сумісний із засобами розробки Microsoft Visual C++ 6.0 та Microsoft Visual Studio .NET, тобто може бути вбудований у відповідні середовища розробки. Крім того, цей компілятор дозволяє вести розробку 64-розрядних програм для операційних систем, що виконуються на процесорах Itanium/Itanium 2, з допомогою Microsoft Visual Studio на 32-розрядному процесорі Pentium із застосуванням 64-розрядного компілятора Intel Fortran Compiler. При налагодженні коду цей компілятор дозволяє використовувати налагоджувач для платформи Microsoft .NET.

За наявності встановленого продукту Compaq Visual Fortran 6.6 можна використовувати замість вихідного компілятора Intel Fortran Compiler 7.1, оскільки ці компілятори сумісні на рівні вихідного коду.

Компілятор Intel Fortran Compiler 7.1 для Windows повністю сумісний зі стандартом ISO Fortran 95 і підтримує створення та налагодження програм, що містять код двома мовами - С і Fortran.

Компілятори для платформи Linux

Intel C++ Compiler 7.1 для Linux

Ще один компілятор, що побачив світ на початку року, Intel C++ Compiler 7.1 для Linux, дозволяє досягти високого ступеня оптимізації коду для процесорів Intel Itanium, Intel Itanium 2, Intel Pentium 4, Intel Pentium M. Цей компілятор повністю сумісний з компілятором GNU C на рівні вихідного коду та об'єктних модулів, що без додаткових витрат дозволяє здійснювати міграцію на нього додатків, створених за допомогою GNU C. операційні системи SCO, ранні версії Sun Solaris та ін), а це означає повну сумісність із компілятором gcc 3.2 на рівні двійкового коду. Нарешті, за допомогою компілятора Intel C++ Compiler 7.1 для Linux можна навіть перекомпілювати ядро ​​Linux, зробивши кілька незначних змін у вихідному коді.

Intel Fortran Compiler 7.1 для Linux

Компілятор Intel Fortran Compiler 7.1 для Linux дозволяє створювати оптимізований код для процесорів Intel Itanium, Intel Itanium 2, Intel Pentium 4, Intel Pentium M. Даний компілятор повністю сумісний з компілятором Compaq Visual Fortran 6.6 на рівні вихідного коду, дозволяє здійснювати за його допомогою , створених за допомогою Compaq Visual Fortran, таким чином підвищуючи їх продуктивність.

Крім того, вказаний компілятор сумісний з такими утилітами, що застосовуються розробниками, як редактор emacs, налагоджувач gdb, утиліта для складання додатків make.

Як і Windows-версія цього компілятора, Intel Fortran Compiler 7.1 для Linux повністю сумісний зі стандартом ISO Fortran 95 і підтримує створення та налагодження додатків, що містять код двома мовами - С і Fortran.

Слід особливо наголосити, що істотний внесок у створення перерахованих компіляторів Intel внесли спеціалісти Російського центру Intel з розробки програмного забезпечення в Нижньому Новгороді. Докладнішу інформацію про компілятори Intel можна знайти на веб-сайті корпорації Intel за адресою: www.intel.com/software/products/.

Друга частина цієї статті буде присвячена компіляторам Intel, що створюють програми мобільних пристроїв.

Приклади реальних зламів: Intel C++ 7.0 Compiler - Архів WASM.RU

…компілятор Intel C++ 7.0 дохитався глибокої ночі, години десь о п'ятій ранку. Спати хотілося неймовірно, але й цікавість: був посилений захист чи ні, теж роздирало. Вирішивши, що доки не розберуся із захистом я все одно не засну, я, відкривши нову консоль, і перевстановивши системні змінні TEMP і TMP на каталог C:\TEMP, нашвидкуруч набив непристойно довге ім'я інсталятора W_CC_P_7.0.073.exe в командному рядку(необхідність у встановленні змінних TEMP і TMP пояснюється тим, що у Windows 2000 вони за умовчанням вказують на дуже глибоко вкладений каталог, а інсталятор Intel C++ - та й не тільки він - не підтримує шляхів такого величезного розміру).

Відразу ж з'ясувалося, що політика захисту була кардинально переглянута, і тепер наявність ліцензії перевірялася вже на стадії встановлення програми (у версії 5.x установка здійснювалася без проблем). ОК, даємо команду dir і дивимося на вміст того, з чим нам зараз належить воювати:

    Вміст папки C:\TMP\IntelC++Compiler70

    17.03.2003 05:10

    html

    17.03.2003 05:11

    x86

    17.03.2003 05:11

    Itanium

    17.03.2003 05:11

    notes

    05.06.2002 10:35 45 056 AutoRun.exe

    10.07.2001 12:56 27 autorun.inf

    29.10.2002 11:25 2 831 ccompindex.htm

    24.10.2002 08:12 126 976 ChkLic.dll

    18.10.2002 22:37 552 960 chklic.exe

    17.10.2002 16:29 28 663 CLicense.rtf

    17.10.2002 16:35 386 credist.txt

    16.10.2002 17:02 34 136 Crelnotes.htm

    19.03.2002 14:28 4 635 PLSuite.htm

    21.02.2002 12:39 2 478 register.htm

    02.10.2002 14:51 40 960 Setup.exe

    02.10.2002 10:40 151 Setup.ini

    10.07.2001 12:56 184 setup.mwg

    19 файлів 2 519 238 байт

    6 папок 886571008 байт вільно

Ага! Програма установки setup.exe займає лише сорок із хвостиком кілобайт. Дуже добре! У такий обсяг серйозний захист навряд чи сховаєш, а якщо навіть так - цей крихітний файл нічого не варто проаналізувати повністю - до останнього байта дизассемблерного лістингу. Втім, не факт, що захисний код розташований саме в setup.exe, він може знаходитися і в іншому місці, ось наприклад… ChkLic.dll/ChkLic.exe, що займають у сукупності трохи менше ніж сімсот кілобайт. Стривай, який такий ChkLic? Це скорочення від Check License чи що?! Гм, у хлопців із Intel очевидно серйозні проблеми із почуттям гумору. Краще б вони назвали цей файл "Hack Me" слово честі! Гаразд, судячи з обсягу, ChkLic це той самий FLEX lm і є, а з ним ми вже стикалися (див. "Intel C++ 5.0 Compiler") і приблизно уявляємо як його ламати.

Даємо команду "dumpbin /EXPORTS ChkLic.dll" для дослідження функцій, що експортуються, і... міцно тримаємося за Клаву, щоб не впасти зі стільця:

    Dump of file ChkLic.dll

  1. Section contains the following exports for ChkLic.dll

    0 characteristics

    3DB438B4 time date stamp Mon Oct 21 21:26:12 2002

  2. 1 number of functions

    1 number of names

    ordinal hint RVA name

    1 0 000010A0 _CheckValidLicense

Чорт забирай! Захист експортує лише одну-єдину функцію із чудовим ім'ям CheckValidLicense. "Чудовим" - тому, що призначення функції стає зрозумілим її назви і з'являється можливість уникнути копіткого аналізу дизассемблерного коду. Ну ось, відбили весь інтерес ... краще б вони її по ординалу експортували чи, або, принаймні, охрестили її якимось відлякуючим ім'ям типу DES Decrypt.

…розмріялися! Гаразд, повернемося до наших баранів. Давайте міркувати логічно: якщо весь захисний код зосереджений безпосередньо в ChkLic.dll (а, судячи з "навісного" характеру захисту, це дійсно так), то весь "захист" зводиться до виклику CheckValidLicense з Setup.exe та перевірки поверненого нею результату. Тому для "злому" достатньо лише пропасти ChkLic.dll, змушуючи функцію ChekValidLicense завжди повертати ... так, до речі, що вона повинна повертати? Точніше: яке саме значення, що повертається, відповідає успішній перевірці ліцензії? Ні, не поспішайте дизассемблировать setup.exe для визначення, адже можливих варіантів не так вже й багато: або FALSE, або TRUE. Ви робите ставку з TRUE? Що ж, у якомусь сенсі це логічно, але з іншого боку: чому ми, власне, вирішили, що функція CheckValidLicense повертає саме прапор успішності операції, а не код помилки? Адже має вона якось мотивувати причини відмови встановлювати компілятор: файл з ліцензією не знайдений, файл пошкоджений, ліцензія прострочена і так далі? Добре спробуємо повернути нуль, а якщо це не прокотить, повернемо одиницю.

ОК, пристібайтеся, поїхали! Запускаємо HIEW, відкриваємо файл ChkLic.dll. до таблиці експорту, отриманої за допомогою dumpbin, визначаємо адресу функції CheckValidLicense (в даному випадку 010A0h) і через "10A0" переходимо в її початок. Тепер, - ріжемо по "живому", перезаписуючи поверх старого коду "XOR EAX, EAX/RETN 4". Чому саме "REN 4", а не просто "RET"? Та тому, що функція підтримує угоду stdcall, про що можна дізнатися глянувши в HIEW"e на її епілог (просто прогортайте екран дизассемблера вниз до тих пір, поки не зустрінете RET).

Перевіряємо ... Це працює! Незважаючи на відсутність ліцензії, інсталятор, не ставлячи зайвих питань, розпочинає встановлення! Отже, захист впав. Ой, не віриться нам, що все так просто і, щоб не сидіти, тупо уп'явшись у монітор в очікуванні завершення процесу інсталяції програми, ми нацьковуємо на setup.exe свій улюблений дизассемблер IDA. Перше, що кидається у вічі, відсутність CheckValidLicense у списку імпортованих функцій. Можливо, вона файл ChkLic.exe якось запускає? Пробуємо знайти відповідне посилання серед автоматично розпізнаних рядків: "~View аNames", "ChkLic"… ага, рядки "Chklic.exe" тут взагалі немає, зате виявляється "Chklic.dll". Ага, зрозуміло, значить, бібліотека ChkLic завантажується явним компонуванням через LoadLibrary. І перехід по перехресному засланню підтверджує це:

    Text:0040175D push offset aChklic_dll; lpLibFileName

    Text:00401762 call ds:LoadLibraryA

    Text:00401762; завантажуємо ChkLic.dll ^^^^^^^^^^^^^^^^^

    Text:00401762;

    Text:00401768 mov esi, eax

    Text:0040176A push offset a_checkvalidlic; lpProcName

    Text:0040176F push esi; hModule

    Text:00401770 call ds:GetProcAddress

    Text:00401770; отримуємо адресу функції CheckValidLicense

    Text:00401770;

    Text:00401776 cmp esi, ebx

    Text:00401778 jz loc_40192E

    Text:00401778; якщо такої бібліотеки немає, то виходимо із програми встановлення

    Text:00401778;

    Text:0040177E cmp eax, ebx

    Text:00401780 jz loc_40192E

    Text:00401780; якщо такої функції у бібліотеці немає, то виходимо з установки

    Text:00401780;

    Text:00401786 push ebx

    Text:00401787 call eax

    Text:00401787; викликаємо функцію ChekValidLicense

    Text:00401787;

    Text:00401789 test eax, eax

    Text:0040178B jnz loc_4019A3

Text:0040178; якщо функція повернула не нуль, то виходимо із програми установки

Неймовірно, але цей жах примітивний захист побудований саме так! Причому півметровий файл ChkLic.exe взагалі не потрібен! І заради чого варто тягнути його з Інтернету? До речі, якщо ви надумаєте зберігати дистриб'ютив компілятора (увага: я не говорив "поширювати"!), то для економії дискового місця ChkLic.* можна стерти: або пропавши setup.exe, назавжди відучивши його до них звертатися, або ж просто створивши свою власну ChkLic.dll, що експортує stdcall функцію CheckValidLicence вигляду: int CheckValidLicence(int some_flag) ( return 0;)

Так, поки ми все це обговорювали, інсталятор закінчив установку компілятора і успішно завершив свою роботу. Чи цікаво запуститься чи компілятор або все найцікавіше тільки починається? Гаряче спускаємося вниз по розгалуженій ієрархії вкладених папок, знаходимо icl.exe, який як і слід очікувати, знаходиться в каталозі bin, натискаємо і… Компілятор природно не запускається, посилаючись на те, що "icl:error: без якої він не може продовжити свою роботу.

Виходить, що Intel застосувала багаторівневий захист і перший рівень виявився грубим захистом від дурнів. Що ж! Ми приймаємо цей виклик і, спираючись на попередній досвід, машинально шукаємо файл LMGR*.DLL в каталозі компілятора. Марно! Цього разу такого файлу тут не виявляється, зате з'ясовується, що icl.exe сильно набрав ваги, переваливши за позначку шестисот кілобайт… Стоп! А чи не прилінковано розробники компілятора цей самий FLEX lm статичним компонуванням? Дивимося: у Intel C++ 5.0 сума розмірів lmgr327.dll та icl.exe становила 598 Кб, а зараз одні лише icl.exe займає 684 Кб. З урахуванням виправлення на природне старече "ожиріння", цифри дуже добре сходяться. Значить, FLEX lm! Ой ой! А тепер, - без символічних імен функцій, ламати захист буде набагато важче... Втім, не будемо раніше панікувати! Давайте думати тільки спокійно! Навряд чи команда розробників повністю переписала весь код, що взаємодіє з цим "конвертним" захистом. Швидше за все, її "удосконалення" лише зміною типу компонування і закінчилося. А якщо так, то шанси зламати програму, як і раніше, великі!

Пам'ятаючи про те, що минулого разу захисний код знаходиться у функції main, ми, визначивши її адресу, просто встановлюємо точку зупинки і, дочекавшись випливання відладчика, тупо трасуємо код, поперемінно поглядаючи то на відладчик, то на вікно виведення програми: чи не з'явилася там лайливе повідомлення? При цьому всі умовні переходи, що зустрілися нам, ми відзначаємо на окремому аркуші паперу (або відкладаємо у своїй власній пам'яті, якщо ви так хочете), не забувши вказати чи виконувався кожен умовний перехід чи ні… Стоп! Щось заговорилися ми з вами, а лайливе повідомлення вже вискочило! ОК добре! Подивимося, який умовний перехід відповідав. Наші записи показують, що останнім переходом, що зустрівся, був умовний перехід JNZ, розташований за адресою 0401075h і "реагує" на результат, поверненою процедурою sub_404C0E:

  • Text:0040107F loc_40107F: ; CODE XREF: _main+75^j

    Text:0040107F mov eax, offset aFfrps; "FFrps"

    Text:00401084 mov edx, 21h

    Text:00401089 call sub_404C0E

    Text:0040108E test eax, eax

    Text:00401090 jnz short loc_40109A

    Очевидно, що sub_404C0E і є та сама захисна процедура, яка здійснює перевірку ліцензії на її наявність. Як її обхитрити? Ну, тут багато варіантів ... По-перше, можна, вдумливо і скрупульозно проаналізувати вміст sub_404C0E на з'ясування: що саме і як саме вона перевіряє. По-друге, можна просто замінити JNZ short loc_40107F на JZ short loc_40107F або навіть NOP, NOP. По-третє, команду перевірки результату повернення TEST EAX, EAX можна перетворити на команду установки нуля: XOR EAX, EAX. По-четверте, можна пропасти саму sub_404C0E, щоб вона завжди повертала нуль. Не знаю, як ви, але мені найбільше сподобався спосіб номер три. Змінюємо два байти і запускаємо компілятор. Якщо жодних інших перевірок його "ліцензійності" у захисті немає, то програма запрацює і відповідно навпаки. (Як ми пам'ятаємо, у п'ятій версії таких перевірок було дві). Вражаюче, але компілятор більше не лається і працює! Справді, як і слід очікувати, його розробники анітрохи не посилили захист, а, навпаки, навіть послабили його! Кріс Касперський

  • Компілятори Intel C++ та Fortran та бібліотека MKL

    Поряд із стандартними для Linux компіляторами GNU, на кластерах обчислювального комплексу НДЦ встановлено компілятори Intel C++ і Fortran. В даний час (початок 2006 року) на всіх кластерах встановлені компілятори версії 9.1. Ця сторінка присвячена опису найважливіших опцій та налаштувань цих компіляторів, а також їх основних відмінностей від компіляторів GNU. Сторінка орієнтована, в основному, на користувачів кластерів НДВЦ МДУ, але може бути корисною й іншим російськомовним користувачам. Тут не порушуються питання, пов'язані з компіляцією для платформи IA-64.

    Також на всіх кластерах встановлено бібліотеку Intel Kernel Math Library(MKL) Версія 8.0.2. Бібліотека знаходиться в каталозі /usr/mkl. Звертаємо увагу на те, що в каталозі lib доступні підкаталоги 32, 64 та em64t. На кластері Ant необхідно використовувати бібліотеки з підкаталогу em64t, а на інших кластерах - з підкаталогу 32. Вся необхідна документація та приклади можна отримати з каталогу /usr/mkl/doc.

    Навіщо знадобилися нові компілятори?

    Необхідність нових компіляторів виникла, головним чином, а) для підтримки програмування мовою Фортран 90, а також б) для більш потужної оптимізації програм мовою Фортран, ніж забезпечує компілятор g77, використовує трансляцію в мову Сі і потім компіляцію за допомогою gcc.

    Цим вимогам задовольняють компілятори PGI (Portland Group), але компанія-розробник відмовилася поставляти їх до Росії.

    Як користуватися?

    Компілятори Intel викликаються за допомогою команд icc(C або C++), icpc(C++) та ifort(Фортран 77/90). Команди mpicc, mpiCC і mpif77 для компіляції та складання MPI-програм також налаштовані використання компіляторів Intel.

    Зберігається також можливість користуватися компіляторами GNU за допомогою mpigcc, mpig++ і mpig77 (Фортран 90 не підтримується).

    Вхідні файли

    За замовчуванням файли з розширенням .cppі .cxxвважаються вихідними текстамимовою С++, файли з розширенням .c- вихідними текстами мовою Сі, а компілятор icpc також компілює файли.c як вихідні тексти С++.

    Файли із розширеннями .f, .ftnі .forрозпізнаються як вихідні тексти мовою Фотран, з фіксованою формою запису, а файли .fppі .Fдодатково пропускаються через препроцесор мови Фортран. Файли із розширенням .f90вважаються вихідними текстами Фортран 90/95 із вільною формою запису. Явним чином можна встановити фіксовану або вільну форму запису Фортран-програм за допомогою опцій -FIі -FRвідповідно.

    Файли із розширенням .sрозпізнаються як код мовою асемблера для IA-32.

    Характеристики компіляторів Intel

    Тут ми наводимо характеристики компіляторів Інтел, як вони заявлені розробником у посібнику користувача з деякими коментарями.

    • Значна оптимізація
      мабуть, тут мають на увазі оптимізація коду ще високому рівні, тобто. насамперед, різні перетворення циклів, що з більшим чи меншим успіхом роблять майже всі компілятори
    • Оптимізація обчислень з плаваючою точкою
      мабуть, мається на увазі насамперед максимальне використання команд, реалізованих на апаратному рівні
    • Міжпроцедурні оптимізації
      тобто. глобальна оптимізація всієї програми, на відміну від звичайної оптимізації, яка стосується лише коду конкретних функцій
    • Оптимізація на базі профілів
      тобто. можливість прогнати програму в тестовому режимі, зібрати дані про час проходження тих чи інших фрагментів коду всередині функцій, що часто використовуються, а потім використовувати ці дані для оптимізації
    • Підтримка системи команд SSE у процесорах Pentium III
      Примітка: для обчислювальних завдань найбільший інтерес представляють команди SSE2, тобто. векторні команди над 64-розрядними речовими числами, але вони підтримуються тільки в процесорах Pentium 4, яких у нашому розпорядженні поки що немає
    • Автоматична векторизація
      тобто. знову ж таки, використання команд SSE та SSE2, що вставляються автоматично компілятором
    • Підтримка OpenMP для програмування на SMP-системах
      на кластері рекомендується переважно користуватися інтерфейсом MPI; широке використання OpenMP на кластері не передбачається і таких експериментів поки що не проводилося; але, мабуть, можна користуватися бібліотеками (BLAS та інших.), розпаралеленими для загальної пам'яті.
    • Передвиборка даних
      тобто. мабуть, використання команд попереднього завантаження з пам'яті в кеш даних, які знадобляться через деякий час
    • "Диспетчеризація" коду для різних процесорів
      тобто. можливість генерації коду для різних процесорів в одному файлі, що дозволяє використовувати переваги новітніх процесорів для досягнення на них найбільшої продуктивності, при збереженні двійкової сумісності програм з більш ранніми процесорами; на нашому кластері це не актуально, т.к. використовуються тільки процесори Pentium III, а також не передбачається передача та запуск на інших машинах програм, відкомпілюваних на кластері

    Основні опції компіляторів

    Найцікавішими, звичайно, є опції оптимізації коду. Більшість опцій є загальними для компіляторів С++ та Фортран. Більше докладний описопцій в англомовних посібниках користувача.

    Рівні оптимізації
    ОпціяОпис
    -O0Вимикає оптимізацію
    -O1 або -O2Базова оптимізація швидкість роботи. Вимикається інлайн-вставка бібліотечних функцій. Для компілятора З++ ці опції дають однакову оптимізацію, для компілятора Фортрана опція -O2 краще, т.к. включає ще розкручування циклів.
    -O3Більш потужна оптимізація, включаючи перетворення циклів, передвиборку даних, використання OpenMP. На деяких програмах може не гарантуватись підвищена продуктивність порівняно з -O2. Має сенс використовувати разом із опціями векторизації -xKі -xW.
    -unroll[n]Включає розкручування циклів до n разів.
    Оптимізації під конкретний процесор
    ОпціяОпис
    -tpp6Оптимізація для процесорів Penitum Pro, Pentium II та Pentium III
    -tpp7Оптимізація для процесорів Penitum 4 (ця опція включена за замовчуванням для компілятора IA-32)
    -xMГенерація коду з використанням розширень MMX, специфічних для процесорів Pentium MMX, Pentium II та пізніших
    -xKГенерація коду з використанням розширень SSE, специфічних для процесорів Pentium III
    -xWГенерація коду з використанням розширень SSE2, специфічних для процесорів Pentium 4
    Міжпроцедурна оптимізація
    -ipВключається міжпроцедурна оптимізація всередині одного файлу. Якщо при цьому вказати опцію -ip_no_inlining, то відключаються інлайн-вставки функцій.
    -ipoВключається міжпроцедурна оптимізація між різними файлами
    Оптимізації з використанням профілів
    -prof_genГенерується "профілювальний" код, який буде використаний для профілювання, тобто. збору даних про частоту проходження тих чи інших місць у програмі
    -prof_useПроводиться оптимізація на основі даних, отриманих на етапі профілювання. Має сенс використовувати разом із опцією міжпроцедурної оптимізації -ipo.
    Розпаралелювання для SMP-систем
    -openmpВключається підтримка стандарту OpenMP 2.0
    -parallelВключається автоматичне розпаралелювання циклів

    Продуктивність

    Згідно з результатами прогону тестів SPEC CPU2000, опублікованими на сервері ixbt.com, компілятори Intel версії 6.0 практично скрізь виявилися кращими в порівнянні з компіляторами gcc версій 2.95.3, 2.96 і 3.1 та PGI версії 4.0.2. Ці тести проводилися в 2002 році на комп'ютері процесором Pentium 4/1.7 ГГц та ОС RedHat Linux 7.3.

    Згідно з результатами тестів, проведених компанією Polyhedron, компілятор Intel Fortran версії 7.0 майже скрізь виявився кращим порівняно з іншими компіляторами Fortran 77 для Linux (Absoft, GNU, Lahey, NAG, NAS, PGI). Тільки деякі тести компілятор Intel незначно програє компіляторам Absoft, NAG і Lahey. Ці тести були проведені на комп'ютері із процесором Pentium 4/1.8 ГГц та ОС Mandrake Linux 8.1.

    Компілятори Intel версії 9.1 також обганяють за продуктивністю компіалтори gcc і показують продуктивність порівнянну з Absoft, PathScale і PGI.

    Ми будемо вдячні тим користувачам та читачам, які надішлють нам дані щодо впливу вибору компілятора (GCC або Intel) та опцій оптимізації на швидкість роботи на їхніх реальних завданнях.

    Бібліотеки

    Компілятор мови Сі використовує runtime-бібліотеку, розроблену в рамках проекту GNU ( libc.a).

    Разом із компілятором Intel C++ поставляються такі бібліотеки:

    • libcprts.a- runtime-бібліотека мови С++ розробки Dinkumware.
    • libcxa.a- Додаткова runtime-бібліотека для С++ розробки Intel.
    • libimf.a- бібліотека математичних функцій розробки Intel, до якої входять оптимізовані та високоточні реалізації тригонометричних, гіперболічних, експоненційних, спеціальних, комплексних та інших функцій (докладніше див. список функцій).
    • libirc.a- runtime-підтримка профілювання (PGO) та "диспетчеризації" коду залежно від процесора (див. вище).
    • libguide.a- Реалізація OpenMP.

    У цьому переліку перераховані статичних бібліотек, але більшість їх є також динамічні, тобто. підключаються під час запуску, варіанти ( .so).

    Разом із компілятором Фортрану поставляються такі бібліотеки: libCEPCF90.a, libIEPCF90.a, libintrins.a, libF90.a, також використовується бібліотека математичних функцій libimf.a.

    Складання виконуваного файлу

    Підключення бібліотек можливе статичне (під час збирання) або динамічне (під час запуску програми). Динамічний підхід дозволяє зменшити розмір виконуваного файлу, дозволяє розділяти в пам'яті ту саму копію бібліотеки, але для цього необхідно встановити на кожному вузлі, де будуть запускатися програми, повний набір динамічних бібліотек, що використовуються.

    Таким чином, якщо Ви встановили компілятор Intel на своїй машині з Linux і хочете запускати зібрані файли на інших машинах, то потрібно або використовувати статичне складання (що простіше) або скопіювати на ці машини динамічні бібліотеки Intel (зазвичай з директорії виду /opt/intel /compiler70/ia32/lib) в одну з директорій, перерахованих у файлі /etc/ld.so.conf, а також подбати про те, щоб на цих машинах було встановлено однаковий набір динамічних бібліотек GNU/Linux.

    За замовчуванням всі бібліотеки розробки Intel (крім libcxa.so) підключаються статично, а всі системні бібліотеки Linux та бібліотеки GNU підключаються динамічно. За допомогою опції -staticможна змусити збирач (редактор зв'язків) підключити всі бібліотеки статично (що збільшить обсяг файлу, що виконується), а за допомогою опції -i_dynamicможна динамічно підключати всі бібліотеки розробки Intel.

    При підключенні додаткових бібліотек за допомогою опції виду -lБібліотекаможе знадобитися використовувати опцію -Lдиректорія, щоб встановити шлях, де розміщуються бібліотеки.

    За допомогою опцій -Bstaticі -Bdynamicявно можна задавати динамічне або статичне підключення кожної з бібліотек, заданих у командному рядку.

    За допомогою опції -cзбирання виконуваного файлу відключається і провадиться тільки компіляція (генерація об'єктного модуля).

    Спільне використання модулів на Фортрані та Сі

    Щоб спільно використовувати модулі, написані мовами Фортран і Сі, необхідно узгодити назву процедур в об'єктних модулях, передачу параметрів, а також доступ до глобальних змінних, якщо такі є.

    За промовчанням компілятор Intel Fortran переводить імена процедур у нижній регістр і додає в кінець імені знак підкреслення. Компілятор Сі ніколи не змінює імена функцій. Таким чином, якщо ми хочемо з модуля на Фортрані викликати функцію або процедуру FNNAME, реалізовану на Сі, то в модулі на Сі вона повинна називатися fnname_.

    Компілятор Фортрану підтримує опцію -nus [ім'я файлу], яка дозволяє вимкнути додавання символів підкреслення до внутрішніх імен процедур. Якщо задано ім'я файлу, це робиться тільки для імен процедур, перелічених у заданому файлі.

    За замовчуванням, на Фортрані параметри передаються за посиланням, а Сі — завжди за значенням. Таким чином, при викликі Фортран-процедури з модуля на Сі ми повинні як параметри передавати покажчики на відповідні змінні, що містять значення фактичних параметрів. При написанні на Сі функції, яку треба буде викликати з модуля на Фортрані, ми повинні описувати формальні параметри як покажчики відповідних типів.

    У модулях на Сі можливе використання COMMON-блоків, визначених усередині модулів на Фортрані (докладніше про це див. Intel Fortran Compiler User's Guide, розділ Mixing C and Fortran).

    Спільне використання компіляторів Intel та GCC

    Об'єктні модулі мовою Сі, отримані компілятором Intel C++, сумісні з модулями, отриманими компілятором GCC та бібліотекою GNU для мови Сі. Таким чином, ці модулі можуть спільно використовуватися в одній програмі, що збирається за допомогою команд icc або gcc, але для коректного підключення бібліотек Intel рекомендується використовувати icc.

    Компілятор Intel підтримує ряд нестандартних розширень мови Сі, які використовуються в рамках проекту GNU і підтримуються компілятором GCC (але не всі з них, див. тут).

    Про сумісність об'єктних модулів мовами С++ та Фортран у посібнику користувача нічого не сказано, мабуть, вона не підтримується.

    Підтримка стандартів

    Компілятор Intel C++ Compiler 7.0 for Linux підтримує стандарт мови Сі ANSI/ISO (ISO/IEC 9899/1990). Можливе встановлення суворої сумісності зі стадартом ANSI C ( -ansi) або розширеного діалекту ANSI C ( -Xa). При використанні опції -C99

  • Посібники з компіляторів у форматі HTML (доступні в "онлайн" на нашому сервері, але потрібна підтримка мови Java)
    • Intel C++ Compiler User's Guide.
    • Intel Fortran Compiler User's Guide.
  • Посібники з компіляторів англійською мовою у форматі PDF (потрібен програма Acrobat Reader, потрібно завантажити PDF-файли на свій комп'ютер)
    • Посібник користувача з компілятора Intel С++: Intel C++ Compiler User's Guide (1.3 Мбайт, 395 сторінок).
    • Посібник користувача компілятора Intel Fortran: Intel Fortran Compiler User's Guide (1.1 Мбайт, 285 сторінок).
    • Довідник програміста мовою Фортран: Intel Fortran Programmer's Reference (7 Мбайт, 566 сторінок).
    • Довідник з бібліотек для мови Фортран: Intel Fortran Libraries Reference Manual (9.5 Мбайт, 881 сторінка).
  • Посібник з відладчика Intel Application Debugger.
  • Порівняння компіляторів на тестах SPEC CPU2000 (стаття на сайті ixbt.com російською мовою).
  • На сайті компанії Polyhedron представлені результати порівняння різних компіляторів.