СРАВНЕНИЕ ЭФФЕКТИВНОСТИ АВТОВЕКТОРИЗАЦИИ В GCC, CLANG И ICC НА НАБОРЕ ВЫЧИСЛИТЕЛЬНЫХ АЛГОРИТМОВ

СРАВНЕНИЕ ЭФФЕКТИВНОСТИ АВТОВЕКТОРИЗАЦИИ В GCC, CLANG И ICC НА НАБОРЕ ВЫЧИСЛИТЕЛЬНЫХ АЛГОРИТМОВ

Авторы публикации

Рубрика

Информационные технологии

Просмотры

51

Журнал

Журнал «Научный лидер» выпуск # 25 (278), Июнь ‘26

Поделиться

Представлены результаты сравнения автовекторизации в GCC, Clang и ICC на алгоритмах БПФ, умножения матриц и свёртки. ICC показывает максимальное ускорение (до 3,12× для БПФ), но уступает при нерегулярном доступе. Даны рекомендации по выбору компилятора.

Введение

Автовекторизация позволяет автоматически генерировать SIMD-инструкции, но её эффективность зависит от компилятора и структуры алгоритма. Цель работы — экспериментально сравнить GCC, Clang и ICC на алгоритмах БПФ, умножения матриц и свёртки. Разработаны тестовые реализации на C/C++, выполнены замеры с включённой и отключённой векторизацией.

Методология экспериментальных исследований

Стенд: Intel Core i7-10700K (3,8 ГГц, 16 потоков), Ubuntu 22.04 LTS, GCC 12.3, Clang 16.0, ICC 2022.2. Профилирование — perf, 10 прогонов, исключение выбросов.

Алгоритмы: БПФ (комплексные числа), умножение матриц (наивное и блочное), свёртка (простая и оптимизированная).

Компиляция: -O3 -march=native; отключение векторизации: -fno-tree-vectorize (GCC), -fno-vectorize (Clang), -no-vec (ICC). Код оптимизирован под выравнивание и контроль алиасинга.

Анализ производительности алгоритмов

Ускорение от автовекторизации зависит от блочной структуры, выравнивания данных и кэш-памяти. Наивная реализация даёт меньший прирост, чем оптимизированная (библиотечная может быть вдвое быстрее). Автовекторизация не заменяет алгоритмическую оптимизацию, а усиливает её при правильной организации данных. Невыровненные обращения требуют дополнительных операций, снижая пропускную способность. Для матриц 512×512 и более ускорение на -O3 значительно. Оптимальный размер блока под кэш L2 улучшает баланс между доступом к памяти и вычислениями [2, с. 16].

Для FFT прирост производительности заметнее на больших массивах: при 2^20 элементов ускорение достигает 2,5–3 раз, при 2^10 — лишь 30–40 %. Это связано с тем, что операции «бабочки» при больших размерах работают в кэше, а при малых накладные расходы на векторизацию снижают выигрыш. Сравнительные результаты для всех трёх компиляторов представлены в таблице 1, а динамика ускорения для GCC визуализирована на рисунке 1.

Таблица 1.

Коэффициент ускорения при автовекторизации для БПФ в зависимости от компилятора и размера массива

Размер массива

GCC 12.3

Clang 16.0

ICC 2022.2

2^10

1,32

1,38

1,45

2^12

1,58

1,67

1,82

2^14

2,01

2,12

2,31

2^16

2,28

2,46

2,68

2^18

2,55

2,78

2,94

2^20

2,71

2,95

3,12

 

Рисунок 1. Зависимость коэффициента ускорения при автовекторизации от размера массива для алгоритма БПФ

Особенности работы алгоритмов свёртки

Нерегулярные шаблоны доступа и условные ветвления мешают формированию SIMD-паттернов. Нерегулярная индексация нарушает выровненные загрузки, снижая выгоду от векторизации. Как отмечается в [1, с. 440], особенности кода могут препятствовать межмодульным преобразованиям, вызывая скалярные откаты и маскированные операции вместо полноширинных инструкций. В свёртках прирост производительности меньше, чем в регулярных ядрах.

Сравнение с включённой и отключённой векторизацией показывает, что при нерегулярном доступе выигрыш ограничен и нестабилен — компилятор не может устранить структурные препятствия. Для устойчивого прироста требуется сочетание векторизации с алгоритмическими преобразованиями (перестановка данных, блокирование) и обеспечение межмодульной интеграции кода.

Интерпретация результатов автовекторизации по компиляторам

Результаты (таблица 1) показывают, что ICC обеспечивает максимальное ускорение на всех размерах массивов благодаря глубокому знанию микроархитектуры Intel и агрессивной оптимизации прологов/эпилогов циклов. Для массива 2^20 ICC достигает 3,12× против 2,95× у Clang и 2,71× у GCC. Однако эффективность ICC снижается при сложных условиях и непредсказуемом доступе — более 25% времени уходит на проверки границ. ICC эффективен для регулярных задач; сложные алгоритмы требуют ручной адаптации.

Clang занимает промежуточное положение, стабильно опережая GCC на 5–8% для больших массивов. Это объясняется более эффективной эвристикой при развёртывании циклов и выборе порядка векторных операций. GCC 12.2, хотя и уступает лидерам, показывает предсказуемую производительность и добавляет проверки выравнивания (потеря 12–15% против Clang), что делает его поведение более консервативным, но надёжным.

Выбор компилятора: ICC — для плотных вычислений на Intel [3, c. 23]; GCC — для баланса производительности и переносимости (-O3 -march=native -ffast-math); Clang — для FFT с нерегулярным доступом [3, c. 39].

Заключение

Эксперимент подтвердил зависимость эффективности автовекторизации от компилятора и типа задачи. ICC показал максимальное ускорение для БПФ (до 3,12× при 2^20), опережая Clang на ~6% и GCC на ~15%. GCC и Clang обеспечивают конкурентоспособную производительность при использовании restrict и AVX2. Рекомендации: ICC — для максимальной производительности на Intel, GCC — для баланса и переносимости, Clang — для задач с нерегулярной структурой данных.

Список литературы

  1. Вьюкова Н.И., Галатенко В.А., Самборский С.В. Директивная и автоматическая векторизации циклов // Программная инженерия. — 2016. — № 10. — С. 435–445
  2. Габрельян Б.В. Технологии высокопроизводительных вычислений. — Ростов-на-Дону: Донской государственный технический университет, 2018. — 26 с.
  3. Штейнберг Б.Я., Штейнберг О.Б. Преобразования программ — фундаментальная основа создания оптимизирующих распараллеливающих компиляторов // Программные системы: теория и приложения. — 2021. — №1. — С. 21–113
Справка о публикации и препринт статьи
предоставляется сразу после оплаты
Прием материалов
c по
Осталось 2 дня до окончания
Размещение электронной версии
Загрузка материалов в elibrary
Публикация за 24 часа
Узнать подробнее
Акция
Cкидка 20% на размещение статьи, начиная со второй
Бонусная программа
Узнать подробнее