Как векторизовать с помощью gcc?

Компилятор gcc серии v4 может автоматически векторизовать циклы с помощью процессора SIMD на некоторых современных процессорах, таких как как чипы AMD Athlon или Intel Pentium/Core. Как это делается?


person casualcoder    schedule 03.01.2009    source источник
comment
Под тем, как это делается, вы имеете в виду, как включить поддержку автовекторизации gcc или как компилятор фактически распознает векторизуемый код и реализует эту поддержку?   -  person Mihai Limbășan    schedule 03.01.2009


Ответы (2)


Исходная страница предлагает подробную информацию о том, как заставить gcc автоматически векторизовать циклы, включая несколько примеров:

http://gcc.gnu.org/projects/tree-ssa/vectorization.html

Хотя примеры великолепны, оказалось, что синтаксис для вызова этих параметров с последней версией GCC немного изменился, см. сейчас:

Таким образом, следующие параметры будут работать для чипов x86 с SSE2, предоставляя журнал циклов, которые были векторизованы:

gcc -O2 -ftree-vectorize -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5

Обратите внимание, что -msse также возможен, но он будет векторизовать циклы только с использованием чисел с плавающей запятой, а не двойных или целых чисел. (SSE2 является базовым для x86-64. Для 32-битного кода также используйте -mfpmath=sse. Это значение по умолчанию для 64-битного, но не 32-битного.)


Современные версии GCC включают -ftree-vectorize в -O3, так что просто используйте это в GCC4.x и более поздних версиях:

gcc   -O3 -msse2 -mfpmath=sse  -ftree-vectorizer-verbose=5

(Clang включает автоматическую векторизацию в -O2. По умолчанию ICC включает оптимизацию + быструю математику.)


Большая часть следующего написана Питером Кордесом, который мог бы просто написать новый ответ. Со временем, по мере изменения компиляторов, параметры и вывод компилятора будут меняться. Я не совсем уверен, стоит ли отслеживать это очень подробно здесь. Комментарии? -- Автор

Чтобы также использовать расширения набора инструкций, поддерживаемые оборудованием, на котором вы компилируете, и настраивать его, используйте -march=native.

Циклы сокращения (например, сумма массива) потребуют OpenMP или -ffast-math для обработки FP-математики как ассоциативной и векторной. Пример компилятора Godbolt с -O3 -march=native -ffast-math, включая сокращение (сумма массива), которое является скалярным без -ffast-math. (Ну, GCC8 и более поздние версии выполняют загрузку SIMD, а затем распаковывают ее в скалярные элементы, что бессмысленно по сравнению с простым развертыванием. Узким местом цикла является задержка одной цепочки зависимостей addss.)

Иногда вам не нужен -ffast-math, просто -fno-math-errno может помочь встроенным математическим функциям gcc и векторизовать что-то, включающее sqrt и/или rint / nearbyint.

Другие полезные параметры включают -flto (оптимизация времени компоновки для встраивания между файлами, постоянного распространения и т. д.) и/или оптимизацию на основе профиля с помощью -fprofile-generate/прогонов тестов с реалистичными входными данными/-fprofile-use. PGO позволяет разворачивать петли для «горячих» петель; в современном GCC это по умолчанию отключено даже при -O3.

person casualcoder    schedule 03.01.2009
comment
-ftree-vectorizer-verbose=5 - это старый синтаксис, теперь нужно использовать более новый синтаксис см.< /а> - person malat; 25.04.2017
comment
Есть ли у GCC более обновленный документ о векторизации? - person Royi; 20.04.2018
comment
Этот флаг и те, которые указаны в ссылке, которую дал @malat, больше не существуют в gcc 8.3. Попытка определить флаги, которые предлагает gcc, немного сложна. Ссылка в моем исходном посте также не обновлялась 8 лет. - person casualcoder; 24.02.2019
comment
@PeterCordes Я не знал -march=native, и это работает очень хорошо. Простое указание флага ускорило мой код в 1,19 раза. Спасибо. - person ynn; 02.04.2020
comment
@casualcoder: исправил это для тебя. GCC -O3 включает автоматическую векторизацию уже в 4.4, а не в GCC8. Я также добавил некоторые другие соответствующие параметры и ссылку на пример на Godbolt. - person Peter Cordes; 04.04.2020
comment
Я мог бы написать новый ответ, но поддерживать существующие ответы на SO, как правило, хорошо. Оставить ответ, получивший наибольшее количество голосов, с чем-то столь же вводящим в заблуждение, как -O3 только векторизация с помощью GCC8, казалось плохой вещью. (Думаю, вы могли бы изменить свой голос за принятие, если бы я написал новый ответ, и ваше редактирование доказало, что вы были активны; чаще у нас есть ответы, давно принятые спрашивающим, который не вернется, так что это еще менее хороший вариант, и этот ответ нуждался в некотором исправлении. Я склонен увлекаться и вносить изменения больше, чем нужно...) - person Peter Cordes; 10.04.2020

Есть gimple (промежуточное представление GCC) pass pass_vectorize. Этот проход включит автоматическую векторизацию на уровне gimple.

Для включения автовекторизации (GCC V4.4.0) нам необходимо выполнить следующие шаги:

  1. Укажите количество слов в векторе в соответствии с целевой архитектурой. Это можно сделать, определив макрос UNITS_PER_SIMD_WORD.
  2. Возможные векторные режимы должны быть определены в отдельном файле, обычно <target>-modes.def. Этот файл должен находиться в каталоге, где находятся другие файлы, содержащие описания машин. (Согласно сценарию конфигурации. Если вы можете изменить сценарий, вы можете поместить файл в любой каталог, в котором вы хотите, чтобы он находился).
  3. Режимы, которые следует учитывать для векторизации в соответствии с целевой архитектурой. Например, 4 слова составят вектор, или восемь полуслов составят вектор, или два двойных слова составят вектор. Детали этого должны быть упомянуты в файле <target>-modes.def. Например:

    VECTOR_MODES (INT, 8);     /*       V8QI V4HI V2SI /
    VECTOR_MODES (INT, 16);    /
    V16QI V8HI V4SI V2DI /
    VECTOR_MODES (FLOAT, 8);   /
               V4HF V2SF */

  4. Постройте порт. Векторизацию можно включить с помощью параметров командной строки -O2 -ftree-vectorize.

person Ganesh Gopalasubramanian    schedule 03.11.2009