Допомогти компілятору у векторизації

Це вільний переклад мого нещодавнього посту на англійській версії Intel Software Network. Так що ті, кому Victoria Zhislina подобається більше vikky13, хто вже бачив цю посаду, можуть одразу прочитати перший та останній абзаци, відсутні в оригіналі.

— Всім здрастуйте, мені потрібний транслятор з української мови в код програми на C++. Ну, тобто, я пишу завдання, а транслятор реалізує її рішення мовою С++. Де можна такий знайти? Якщо для Cі немає, можливо, є для інших мов?

— Є, називається начальник відділу розробки. Пишеш завдання українською — віддаєш підлеглим і все, код готовий! Хоч на Сі, хоч на Дельфі, хоч на Яві. Я перевіряв, чи працює!

Говорять, що це не анекдот, а реальне питання на програмістському форумі. Також кажуть, що людина набагато розумніша за машину, а отже, може їй допомогти — поділитися розумом. Але є чимало випадків, коли робити це точно не варто. Результат буде зворотний очікуваному.

А результат буде доволі несподіваний. Асемблерний листинг на виході компілятора неспростовно показує, що розгорнутий цикл векторизується не вектор. Компілятор генерує інструкції SSE, але тільки скалярні, а не векторні. Зате залишок даних — «хвіст», що містить лише 1-3 елементи даних у нерозгорнутому циклі, векторизується за повною програмою!

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

Висновок :Більше роботи — менша продуктивність. Менше роботи – більше. От би завжди так.

Зауважимо, що Microsoft Compiler, Visual Studio 2010 та 2008 зключем /arch:SSE2 НЕ векторизує наведений вище код ні в розгорнутому ні в згорнутому вигляді. Код, ним виготовлений, дуже схожий і на вигляд і за продуктивністю в обох випадках. Тобто, якщо для компілятора Intel розгортання циклу – шкідливе, то для Microsoft – марно :).

А що якщо ви все ж таки хочете зберегти розгортання циклу — воно дороге вам як пам'ять, але й векторизацію теж хочете?

Тоді використовуйте прагми компілятора Intel як показано нижче:#pragma simd#pragma novector