Нові учасники, C / C + +, Програмування, статті

Ми протестували ще три компілятора, а саме: GNU C + + 2.95.3-7 (вірніше його порт на Windows – mingw), Borland C + + 5.5 та VC.Net (v 7.0) beta 2.

Компілятор GNU C + + (далі gcc) тестувався нами і в інших версіях (менших ніж 2.95.3-7). Причому він щоразу показував трохи розрізняються результати, але так як серйозна відмінність виявилося в і без того спірному тесті
(Докладніше див у коментарі до цього тесту), я не буду тут загострювати увагу на цю особливість. Gcc на сьогодні є і версії 3.х, але вона не була доступна на платформі Windows на час проведення випробувань. І, так як 2.95.3-7 – це практично бета-версія для 3.х, можна закрити на це очі. В майбутньому ми перевіримо ці тести на 3.x і, в разі істотної різниці, опублікуємо результати з нашими коментарями.

Borland C + + 5.5 (далі bcc) – це остання версія компілятора C + + від фірми Borland. Це добротний компілятор, досить точно відповідає стандарту. Інтерес до нього підігрівається ще й тим, що Borland C + + 5.5 став вільно поширюваним.

VC.Net (v 7.0) beta 2 (далі VC7) – це ще бета версія, але його результати вже дозволяють говорити про те, що алгоритми оптимізації в новій версії помітно покращилися. Не всі тести стали виконуватися швидше, але деякі (підрахунок p, і рядковий тест) – безсумнівно.

Тести


Отже перейдемо до самих тестів.


Виклик методу об’єкта (Method call)






























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 1.44
з розворотом циклів 0.37
з “повним” розворотом циклів 0.36
Borland C++ 5.5   9.39
VC.Net (v 7.0) beta 2 З inline-підстановкою 0.00
Без inline-підстановки 0.00

Єдиний, хто не став обтяжувати себе <зайвої> оптимізацією – bcc. Але його результат виявився одним з найгірших поступившись останнє місце тільки явного <Лідеру> VB.

VC7 оптимізував як виклик, так і цикл, в якому цей виклик робився. Причому така поведінка спостерігалося як в режимі з автоматичною inline-підстановкою, так і без цього режиму. По всій видимості, в компілятор був безпосередньо доданий алгоритм оптимізації, викидають порожні виклики, а за відсутності виклику цикл став порожнім і теж був викинутий. З одного боку, це добре, тому що тепер заглушки, залишені в коді, більше не займатимуть процесорного часу. Але з точки зору нашого тесту це погано, тому що його метою є перевірка оптимальності генерованого коду, що виробляє виклик методу. Так що VC7 в цьому тесті можна поставити бублик, навіть незважаючи на настільки чудові результати.

Gcc чудово впорався з цим тестом, хоча ні в одному з варіантів не зміг повністю соптімізіровать весь цикл. По розуму, для заліку потрібно брати результат, отриманий без опцій компілятора, які змушують його розкручувати цикли. Це пов’язано з тим, що цикл в нашому випадку – це не зло, а спосіб змусити компілятор виконувати код достатню кількість разів, щоб займане процесом час можна було виміряти. Враховуючи, що компілятор все одно не зміг повністю соптімізіровать цикл, результати тестів з розкруткою циклів стають марними. Однак ми вирішили залишити його, хоча б заради справедливості. Так що ви можете самі прийняти для себе рішення, як оцінювати gcc.

Ще раз нагадаємо, що не варто звертати особливої ​​уваги на синтетичні тести, бо виграш в даному тесті найчастіше досягається не оптимальністю виклику методу, а іншими оптимізаціями (розкрутка циклу, inline-підстановки …), і тим, що час, що витрачається на виклик, відносно невелика. Дивно те, що цей час виявилося на третину більше, ніж у Delphi, також продукту цієї фірми. Мабуть недарма побутує думка, що Borland злюбив C + +.

Виклик віртуального методу об’єкта (virtual method call)
























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 18.78
з розворотом циклів 18.67
з “повним” розворотом циклів 18.66
Borland C++ 5.5   8.90
VC.Net (v 7.0) beta 2 З inline-підстановкою 5.77
Без inline-підстановки 5.77

VC7 став переможцем цього тесту в загальному заліку, поліпшивши час, показане своїм попередником на 2 сотих секунди :). Таку перемогу можна було б і не вважати перемогою, якби VC7 не показав того ж часу в режимі без автоматичної inline-підстановки (у цьому режимі VC6 показав помітно гірший результат, 6.49 секунди, хоча став минулого разу лідером).

Bcc в черговий раз показав час, хоча і не набагато, але найгірше, ніж Delphi. Що ж, це некритичне відставання, як це було у випадку з VB6, але все одно прикро.

Для gcc цей тест був, мабуть, найбільш невдалим. Gcc примудрився відстати навіть від Java. Причому не допоміг йому навіть варіант компіляції з повною розкручуванням циклів – різниця у швидкості була незначною (18.78 секунд у звичайному режимі і 18.66 в режимі з повною розкручуванням циклів). Назвати цю різницю серйозної (Особливо на тлі такого серйозного відставання) не можна. Мабуть, повсюдне використання COM, як відомо, заснованого на віртуальних виклики, змусило розробників традиційних для Windows компіляторів з більшою ретельністю займатися оптимізацією викликів віртуальних методів.

Доступ до члена класу
























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 4.01
з розворотом циклів 0.40
з “повним” розворотом циклів 0.40
Borland C++ 5.5   6.79
VC.Net (v 7.0) beta 2 З inline-підстановкою 1.44
Без inline-підстановки 4.33

Результати даного тесту схожі на попередній, з тією лише різницею, що VC7 не зміг повністю оптимізувати тест в режимі з автоматичною inline-підстановкою. Це дивно, тому що ми бачили, що VC7 не замислюючись викидає зайві виклики і застосовує оптимізацію до результатів підстановки. В Зрештою, якщо звернення до члена класу замінити на звернення до глобальної змінної, то VC7 спокійно викине цикл, замінивши його константним обчисленням і підставивши його результат в змінну. Коротше кажучи, Microsoft ще є над чим працювати в наступній версії свого компілятора C + +, якщо такий планується.

Gcc продемонстрував відносно непоганий результат, але все таки відстав від лідера (C #). Як і минулого разу, результати з розворотом циклу наводяться виключно в цілях справедливості і не повинні розглядатися як оцінюваних.

Quick Sort (швидке сортування)





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 9.36
з розворотом циклів 9.95
з “повним” розворотом циклів 9.97
Borland C++ 5.5   10.71
VC.Net (v 7.0) beta 2 З inline-підстановкою 8.08
Без inline-підстановки 8.10

Перший не синтетичний тест. Що ж він показав? Власне, показав приблизно ті ж залежності, які ми спостерігали в попередніх тестах. Всс відстав і зайняв місце між Delphi і Java. Gсс був більш щасливий, але розкрутка циклів на реальних задачах не дала приросту продуктивності. Навпаки, тест без розвороту циклів зайняв найменший час, 9.36, з розворотом циклів – середнє, 9.95, з “повним” розворотом циклів – 9.97, а якщо включити одразу обидва варіанти розворотів циклів, то час виконання тесту і зовсім виходить за 10 секунд. Так що дана оптимізація на хороших алгоритмах може дати скоріше уповільнення (хоча і незначне), ніж приріст продуктивності.

Порадував тільки один VC7, який знову зміг підняти планку, на цей раз вже на відчутні півсекунди. Знову повторився приріст не тільки в режимі з автоматичної inline-підстановкою, але і в звичайному.

Бульбашкова сортування





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 5.36
з розворотом циклів 4.81
з “повним” розворотом циклів 4.81
Borland C++ 5.5   5.05
VC.Net (v 7.0) beta 2 З inline-підстановкою 5.00
Без inline-підстановки 5.00

Це перший тест, в якому опція розкрутки циклів у gcc дала приріст продуктивності, тим самим дозволивши gcc зайняти верхню сходинку п’єдесталу пошани. Кривизна алгоритму як би частково компенсувалася розворотом циклу. Проте варіант з “повним” розворотом циклів нічим не відрізнявся від більш простого аналога. Час gcc, показане без оптимізацій розкрутки циклів, виявилося гірше, ніж у більшості учасників, але теж дуже гідним, підтвердивши, що gcc є якісним продуктом. Для порівняння, звичайно ж, потрібно брати результат з розкручуванням циклу.

Порадував цього разу і bcc. Його результат був хоча і не найкращим, але настільки мало відставав від лідера, що bcc можна привітати з непоганим результатом.

Підрахунок p (цілочисельні обчислення)





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 4.10
з розворотом циклів 3.80
з “повним” розворотом циклів 3.80
Borland C++ 5.5   6.84
VC.Net (v 7.0) beta 2 З inline-підстановкою 3.77
Без inline-підстановки 3.77

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

Сподіваємося, що надалі чудові методи оптимізації потраплять і в інші компілятори. Зрештою, Microsoft має повну інформацію про алгоритмах, що застосовуються в обох компіляторах, а всі інші можуть вчитися на досвіді gcc.

Borland показав гідний результат, але, як завжди, трохи гірше ніж у Delphi.

Tree sort





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 12.63
з розворотом циклів 12.56
з “повним” розворотом циклів 12.71
Borland C++ 5.5   11.54
VC.Net (v 7.0) beta 2 З inline-підстановкою 11.34
Без inline-підстановки 11.37

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

Однак зараз хочеться поговорити трохи про інше. Як уже говорилося, в минулій серії швидкість виконання цього тесту в більшій мірі залежить не від якості компілятора, а від якості реалізації Хіпан. За замовчуванням Delphi використовує однопотоковий режим роботи з хіпом, і деякі читачі (з одночасно знайомим і загадковим ім’ям Anonym) засумнівалися в тому, що реалізація Хіпан в Delphi краще, ніж стандартна реалізація в W2k. Обгрунтовувалося це тим, що ми не провели тестів в багатопотоковому режимі. ми вирішив виправити дане упущення.

Для того, щоб включити багатопотоковий режим, ми додали в обробник події FormCreate перемикання властивості IsMultiThread:

procedure TForm1.FormCreate(Sender: TObject);
begin
IsMultiThread := True;
end;

Це дійсно привело до зниження швидкості виконання тесту до 11.51 секунди, але повторне виконання не призвело до якого б то не було збільшення часу. А якщо врахувати, що результати VC6 і Intel C + + були приведені теж для однопотокового режиму, і те, що навіть в цьому випадку Delphi залишилася лідером (Серед тих учасників), то можна сказати, що слова про якість реалізації Хіпан в Delphi абсолютно справедливі. Проте ми не робили тестів на конкурентний доступ до хіпу з декількох потоків, і не можемо сказати, як поведуть себе конкретні реалізації в цьому випадку. Можливо, в майбутньому ми проведемо такий тест.

Поки можна сказати, що першість VC7 кілька затьмарюється тим, що в багатопотоковому режимі час повторного виконання цього тесту значно збільшується. Але, як вже говорилося, це проблема не VC7 як такого, а W2k.

String-тест





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 5.12
з розворотом циклів 5.39
з “повним” розворотом циклів 5.13
Borland C++ 5.5   15.80
VC.Net (v 7.0) beta 2 З inline-підстановкою 4.11
Без inline-підстановки 4.10

Дещо про цьому тесті ми вже сказали. Так що Delphi ми більше чіпати не будемо. Поговоримо краще про інших учасників. На жаль, результати цього тесту не можна назвати задовільними, так як ми не змогли забезпечити однакові умови порівняння навіть для C + +-компіляторів. Справа в тому, що підключення MFC до не Microsoft-івським компіляторам – це непросте завдання, на яку просто не було часу. Особливо це було складно з gcc. Тому ми прийняли рішення скористатися більш стерпної реалізацією з STL – std :: string. Але й тут не все так просто. Існує безліч реалізацій STL, і наші піддослідні (а саме bcc і gcc) використовували різні версії. Причому у bcc виявився самий древній і повільний варіант від HP. Проте результати тесту мають право на життя, оскільки швидше за все користуватися програміст буде тим, що є під рукою.

VC7, як і в інших тестах, дещо поліпшив свій результат, але до лідерів не дістав.

Bcc показав зовсім поганий результат, але як уже говорилося, можливо це в більшою мірою залежить не від якості оптимізації, а від якості реалізації
STL.

Float-Тест





























Компілятор Опції Час (с)
GNU C++ 2.95.3-7 (mingw) Без розвороту циклів 14.46
з розворотом циклів 3.34
з “повним” розворотом циклів 3.36
Borland C++ 5.5   15.12
VC.Net (v 7.0) beta 2 З inline-підстановкою 12.26
Без inline-підстановки 12.2

Ще одним тестом, в якому виграє не сильніший, а найхитріший, став
. Так, gcc в звичайному режимі показав абсолютно посередній результат, зайнявши місце між Java і VB6. Однак з включеною опцією розкручування циклів він раптом відразу перемістився на другу позицію (першим, нагадаю, був Intel C + +). Причому я зміг домогтися тільки результату 3.34 секунди, а Юнусов Булат (автор одного з варіантів тесту для gcc) домігся ~ 1.5 секунд. Такий результат вельми добре виглядає, але зовсім непридатний для порівняння, так як він досягається не за рахунок збільшення якості оптимізації обчислень з плаваючою точкою, а за рахунок банальної боротьби з циклом. Усвідомлення цього ще більше наштовхує на думку, що для отримання реалістичних результатів потрібен осмислений алгоритм. Причому до цього алгоритму пред’являються досить строгі вимоги: він повинен в основному складатися з обчислень над змінними типу double, він не повинен містити значних звернень до масивів (інакше мови, виробляють контроль доступу до масивів, будуть у свідомо поганих умовах, та й велика частина тесту буде міряти швидкість доступу до шини пам’яті).

Якщо у когось на прикметі є алгоритм, що задовольняє умовам, перерахованим вище, велике прохання зв’язатися з нами по e-mail (tcs@optim.ru), і передати цей алгоритм.

Подяки


Хочеться подякувати Олександра Корсукова, Булата Юнусова та Ігоря Ткачова, допомагали (своєю особистою працею і радами) в перенесенні коду під gcc і bcc.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*