Восьма версія компіляторів Intel. Компілятори для платформи Microsoft Windows

Ти – не раб!
Закритий освітній курс для дітей еліти: "Істинне облаштування світу".
http://noslave.org

Матеріал з Вікіпедії – вільної енциклопедії

Intel C++ Compiler
Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).
Тип
Автор

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Розробник
Розробники

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Написана на

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Інтерфейс

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Операційна система
Мови інтерфейсу

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Перший випуск

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Апаратна платформа
остання версія
Кандидат у релізи

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Бета-версія

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Альфа-версія

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Тестова версія

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Формати файлів, що читаються

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Формати файлів, що створюються

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Стан

Помилка Lua в Модуль:Wikidata на рядку 170: attempt to index field "wikibase" (a nil value).

Ліцензія

Основні можливості:

  • Векторизація для SSE, SSE2, SSE3, SSE4

Компілятор підтримує стандарт OpenMP 3.0 для написання паралельних програм. Також містить модифікацію OpenMP під назвою Cluster OpenMP, за допомогою якої можна запускати програми написані відповідно до OpenMP на кластерах, що використовують MPI.

Intel C++ Compiler використовує фронтенд (частина компілятора, що займається синтаксичним аналізом програми, що компілюється) від Edison Design Group. Цей фронтенд використовується компіляторами SGI MIPSpro, Comeau C++, Portland Group.

Цей компілятор широко використовується для компіляції бенчмарків SPEC CPU.

Існує 4 серії продуктів від Intel, що містять компілятор:

  • Intel C++ Compiler Professional Edition
  • Intel Cluster Toolkit (Compiler Edition)

До недоліків Linux версії компілятора можна віднести часткову несумісність із GNU-розширеннями мови Сі (підтримувані компілятором GCC), що може спричинити проблеми при компіляції деяких програм.

Експериментальні варіанти

Публікувалися такі експериментальні варіанти компілятора:

  • Intel STM Compiler Prototype Edition від 17 вересня 2007 року. Підтримка Software Transactional Memory (STM). Випущений для Linux та Windows, лише для IA-32 (x86-процесорів);
  • Intel Concurrent Collections for C/C++ 0.3 від вересня 2008 року. Містить механізми, що полегшують написання паралельних C++ програм.

Основні прапори

Windows Linux, MacOSX Опис
/Od -O0 Вимкнути оптимізацію
/O1 -O1 Оптимізувати для мінімізації розміру файлу
/O2 -O2 Оптимізувати підвищення швидкості. Включено деякі оптимізації
/O3 -O3 Включити всі оптимізації з O2. Також виконати інтенсивні оптимізації циклів
/Oip -Oip Включити пофайлову міжпроцедурну оптимізацію
/Oipo -Oipo Включити глобальну міжпроцедурну оптимізацію
/QxO -xO Дозволити використання SSE3, SSE2 та SSE розширень для процесорів виробництва будь-яких компаній
/fast -fast "Швидкий режим". Еквівалентний опціям "/O3 /Qipo /QxHost /no-prec-div" на Windows та "-O3 -ipo -static -xHOST -no-prec-div" на Linux. Зауважте, прапорець -xHOST означає оптимізацію для того процесора, на якому запущений компілятор.
/Qprof-gen -prof_gen Створити інструментовану версію програми, яка збере профіль виконання
/Qprof-use -prof_use Скористайтеся профільною інформацією від запусків програми, зібраної з прапором prof_gen.

Напишіть відгук про статтю "Intel C++ compiler"

Примітки

Див. також

Посилання

Уривок, що характеризує Intel C++ compiler

А ще, вона повернулася для того, щоб востаннє побачити Білого Волхва... Свого чоловіка та найвірнішого друга, якого так і не змогла ніколи забути. У своєму серці вона вибачила його. Але, на його великий жаль, не змогла принести йому прощення Магдалини. Так що, як бачиш, Ізидора, велика християнська байка про «всепрощення» це просто дитяча брехня для наївних віруючих, щоб дозволити їм творити будь-яке Зло, знаючи, що чого б вони не зробили, зрештою їх вибачать. Але прощати можна лише те, що по-справжньому гідне прощення. Людина повинна розуміти, що за будь-яке здійснене Зло їй доводиться відповідати... І не перед якимось таємничим Богом, а перед собою, змушуючи себе жорстоко страждати. Магдалина не пробачила Владико, хоч глибоко поважала і щиро любила його. Так само, як вона не зуміла пробачити і всіх нас за страшну смерть Радомира. Адже саме ВОНА найкраще розуміла – ми могли допомогти йому, могли врятувати його від жорстокої смерті... Але не захотіли. Вважаючи провину Білого Волхва надто жорстокою, вона залишила його жити з цією провиною, ні на хвилину не забуваючи її... Вона не захотіла дарувати йому легкого вибачення. Ми так ніколи й не побачили її. Як ніколи не побачили та їхніх малюків. Через одного з лицарів свого Храму – нашого волхва – Магдалина передала відповідь Владиці на його прохання повернутися до нас: «Сонце не сходить одного дня двічі... Радість вашого світу (Радомир) вже ніколи не повернеться до вас, як не повернуся до вас і я... Я знайшла свою ВІРУ і свою ПРАВДУ, вони ЖИВІ, ваша ж - МЕРТВА... Оплакуйте своїх синів - вони вас любили. Я ж ніколи не пробачу вам їхньої смерті, доки жива. І нехай ваша вина залишається з вами. Можливо, колись вона принесе вам Світло та Прощення... Але не від мене». Голову ж Волхва Іоанна не привезли в Метеору з тієї ж причини - ніхто з лицарів Храму не захотів повертатися до нас... Ми втратили їх, як втрачали не раз багатьох інших, хто не хотів зрозуміти і прийняти наших жертв... Хто так а, як ти, пішли, засуджуючи нас.
У мене паморочилося в голові!.. Як спраглий, вгамовуючи свій вічний голод знання, я жадібно вбирала потік дивовижної інформації, щедро дарованої Північчю... І мені хотілося набагато більше!.. Хотілося знати все до кінця. Це було ковтком свіжої води у випаленому болю та бідах пустелі! І я ніяк не могла вдосталь напитися.
– У мене тисячі запитань! Але не залишилося часу... Що ж мені робити, Північ?
– Запитуй, Ізидоро!.. Запитуй, я спробую відповісти тобі...
- Скажи, Північ, чому мені здається, що в цій історії як би з'єдналися дві історії життя, обплетені схожими подіями, і подаються вони, як життя однієї особи? Чи я не права?
- Ти абсолютно права, Ізідоро. Як я вже казав тобі раніше, «сильні цього світу», хто створював фальшиву історію людства, «наділи» на справжнє життя Христа чуже життя іудейського пророка Джошуа (Joshua), який жив півтори тисячі років тому (з часу розповіді Півночі). І не тільки його самого, а й його сім'ї, його рідних та близьких, його друзів та послідовників. Адже саме у дружини пророка Джошуа, юдейки Марії, була сестра Марта та брат Лазар, сестра його матері Марія Якобе, та інші, яких ніколи не було поряд із Радомиром та Магдалиною. Так само, як не було поруч із ними і чужих «апостолів» – Павла, Матвія, Петра, Луки та інших...
Саме сім'я пророка Джошуа перебралася півтори тисячі років тому в Прованс (який на той час називався Гаул (Transalpine Gaul), в грецьке місто Массалію (теперішній Марсель), оскільки Массалія на той час була «воротами» між Європою та Азією, і це було найлегшим шляхом для всіх «гнаних», щоб уникнути переслідувань та бід.

Наприкінці 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, щоб вона завжди повертала нуль. Не знаю, як ви, але мені найбільше сподобався спосіб номер три. Змінюємо два байти і запускаємо компілятор. Якщо жодних інших перевірок його "ліцензійності" у захисті немає, то програма запрацює і відповідно навпаки. (Як ми пам'ятаємо, у п'ятій версії таких перевірок було дві). Вражаюче, але компілятор більше не лається і працює! Справді, як і слід очікувати, його розробники анітрохи не посилили захист, а, навпаки, навіть послабили його! Кріс Касперський



  • Завантаження...
    Top