Компилятор gcc
серии v4 может автоматически векторизовать циклы с помощью процессора SIMD на некоторых современных процессорах, таких как как чипы AMD Athlon или Intel Pentium/Core. Как это делается?
Как векторизовать с помощью gcc?
Ответы (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.
-ftree-vectorizer-verbose=5
- это старый синтаксис, теперь нужно использовать более новый синтаксис см.< /а>
- person malat; 25.04.2017
-O3
. Предпочтите это. (В наши дни он не включает развертывание циклов по умолчанию; в идеале используйте -fprofile-generate
+ -fprofile-use
для развертывания горячих циклов.) Также предпочтите -O3 -march=native -ffast-math
при компиляции только для вашего собственного компьютера. См. также помощь по оптимизации цикла C для окончательного назначения для некоторых примеров автоматической векторизации и автоматического распараллеливания GCC с недревним gcc.
- person Peter Cordes; 25.02.2019
-march=native
, и это работает очень хорошо. Простое указание флага ускорило мой код в 1,19 раза. Спасибо.
- person ynn; 02.04.2020
-O3
только векторизация с помощью GCC8, казалось плохой вещью. (Думаю, вы могли бы изменить свой голос за принятие, если бы я написал новый ответ, и ваше редактирование доказало, что вы были активны; чаще у нас есть ответы, давно принятые спрашивающим, который не вернется, так что это еще менее хороший вариант, и этот ответ нуждался в некотором исправлении. Я склонен увлекаться и вносить изменения больше, чем нужно...)
- person Peter Cordes; 10.04.2020
Есть gimple (промежуточное представление GCC) pass pass_vectorize
. Этот проход включит автоматическую векторизацию на уровне gimple.
Для включения автовекторизации (GCC V4.4.0) нам необходимо выполнить следующие шаги:
- Укажите количество слов в векторе в соответствии с целевой архитектурой. Это можно сделать, определив макрос
UNITS_PER_SIMD_WORD
. - Возможные векторные режимы должны быть определены в отдельном файле, обычно
<target>-modes.def
. Этот файл должен находиться в каталоге, где находятся другие файлы, содержащие описания машин. (Согласно сценарию конфигурации. Если вы можете изменить сценарий, вы можете поместить файл в любой каталог, в котором вы хотите, чтобы он находился). Режимы, которые следует учитывать для векторизации в соответствии с целевой архитектурой. Например, 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 */Постройте порт. Векторизацию можно включить с помощью параметров командной строки
-O2 -ftree-vectorize
.