Поддерживаемые MCST директивы #pragma и !dir$¶
Общая информация¶
В данном документе описываются только собственные директивы #pragma и !dir$. Директивы #pragma, описанные в каких-либо стандартах, описаны в статье Поддерживаемые стандартные директивы #pragma. Те директивы #pragma, которые позаимствованы у gcc, описаны в статье Поддерживаемые GNU директивы #pragma
Директивы #pragma языков C/C++¶
Директивы #pragma для заголовочных файлов¶
#pragma
onceЗапрет повторного включения заголовочного файла. По действию сходно с include guard. Добавляется в самое начало файла
Директивы #pragma для управления диагностическими сообщениями¶
Настроить можно только те диагностические сообщения, которые являются предупреждением (warning)
или замечанием (remark). Под <msg>
подразумевается номер диагностического сообщения, который
печатается в компиляторе при выдаче
#pragma
diag_suppress <msg>
Подавить вывод диагностического сообщения
#pragma
diag_remark <msg>
Поменять уровень диагностического сообщения на “замечание”
#pragma
diag_warning <msg>
Поменять уровень диагностического сообщения на “предупреждение”
#pragma
diag_error <msg>
Поменять уровень диагностического сообщения на “ошибка”
#pragma
diag_default <msg>
Установить для диагностического сообщения поведение по умолчанию
#pragma
diag_once <msg>
Установить для диагностического сообщения режим, в котором оно выдается не более одного раза
#pragma
diagnostic pushСохранить текущие настройки диагностических сообщений в виртуальный стек
#pragma
diagnostic popИзвлечь настройки диагностических сообщений из виртуального стека
Директивы #pragma для для задания идентификационной строки¶
#ident "string"
#pragma
ident "string"
Игнорируются
Директивы #pragma для оптимизации ассемблерных вставок¶
#pragma
asm_inline#pragma
no_asm_inlineУправление inline-подстановкой ассемблерных вставок
#pragma
asm_length (length)
Доступно только для архитектуры E2K. Указание длительности ассемблерной вставки, выраженной в количестве машинных тактов. Для параметра
length
учитываются только значения от 0 до 14. Значения 15 и выше игнорируются
Директивы #pragma для оптимизации ассемблерных вставок¶
#pragma
unknown_control_flow (func_name)
Обработка функции
func_name
аналогично функцииsetjmp
#pragma
no_instrument_function (func_name)
Отказ от инструментирования функции
func_name
Директивы #pragma, указывающие компилятору свойства процедур¶
#pragma
no_inline (func_list)
Запрещает компилятору делать inline-подстановку функций в списке
#pragma
hot (func_list)
Указывает компилятору, что представленные в списке функции являются “горячими”
#pragma
no_side_effect (func_list)
Указывает, что функции не имеют посторонних эффектов (не меняют состояние программы, невидимое в точке вызова). Игнорируется
Директивы #pragma для оптимизации циклов¶
#pragma
unroll (N)
Применить Loop Unrolling на N к ближайшему после объявления директивы циклу. Если параметр опущен, то компилятор это воспринимает, как желание пользователя полностью раскрутить цикл в скалярный код. Дополнительным эффектом применения прагмы является увеличение оценочного количества итераций указанного цикла, если оно не известно точно. Количество итераций вычисляется как
min_ovl * N
, гдеmin_ovl
- минимальное количество итераций, при котором применится оптимизация аппаратного наложения итераций цикла. Для более точного определения количества итераций цикла рекомендуется использовать эту прагму в комбинации с#pragma loop_count (N)
#pragma
split_fuse (N)
Игнорируется
#pragma
loop count (N)
Установить у ближайшего после объявления директивы цикла количество итераций равное N. Игнорируется, если подан реальный профиль через
-fprofile-use
#pragma
vector always
Форсирует применение векторизации к ближайшему после объявления директивы циклу, даже если эвристики оптимизации говорят, что её применение нецелесообразно
#pragma
vector aligned
Говорит компилятору, что все обращения к памяти в ближайшем после объявления директивы цикле являются выровненными, так что векторизация может примениться к этому циклу более эффективно. Величина выравнивания зависит от целевой архитектуры: для Elbrus V1-V4 это 8 байт, для V5 и далее - 16 байт.
#pragma
vector unaligned
Говорит компилятору, что все обращения к памяти в ближайшем после объявления директивы цикле являются невыровненными, поэтому строить динамические проверки выровненности операций обращения к памяти не следует.
#pragma
vector nontemporal
Запрет заведения в кэш-память всех уровней и включение режима write combining (объединение операций в store-буфере) для операций записи в ближайшем после объявления директивы цикле.
#pragma
novectorЗапрет применения векторизации к ближайшему после объявления директивы циклу
#pragma
reduce recurrence
Форсирует разрыв рекурентностей в ближайшем после объявления директивы цикле
#pragma
prefetchФорсирует включение аппаратной предподкачки данных для регулярных операций чтения из памяти в ближайшем после объявления директивы цикле, даже если эвристики оптимизации говорят, что это нецелесообразно; не влияет на автоматическую генерацию операций программной предподкачки
#pragma
noprefetchЗапрет аппаратной предподкачки данных для регулярных операций чтения из памяти в ближайшем после объявления директивы цикле; не влияет на автоматическую генерацию операций программной предподкачки
#pragma
comb_operФорсирует комбинирование пар арифметических операций в двухэтажные операции в ближайшем после объявления директивы цикле, даже если эвристики оптимизации говорят, что это нецелесообразно
#pragma
no_comb_operЗапрещает комбинирование пар арифметических операций в двухэтажные операции в ближайшем после объявления директивы цикле
#pragma
ivdepУказывает, что в ближайшем после объявления директивы цикле, если для пары операций чтения/записи не удалось статически определить их зависимость или независимость, то следует считать, что межитерационные зависимости для этих операций отсутствуют
#pragma
no_damЗапрещает применение динамического разрыва зависимостей (DAM) к ближайшему после объявления директивы циклу. Может быть полезной в случае, когда в цикле есть maybe-зависимости между операциями доступа к памяти, из-за которых применение DAM приводит к частому уходу на компенсирующий код. Прагма имеет эффект только для архитектуры Elbrus.
#pragma
swpФорсирует применение оптимизаций конвейеризации к ближайшему после объявления циклу, выключая проверки эффективности конвейеризации для этого цикла
#pragma
noswpЗапрещает применение оптимизаций конвейеризации к ближайшему после объявления циклу
#pragma
spmvПозиционирует ближайший цикл как цикл умножения разреженных матриц. Это даёт возможность лучше настроить оптимизации и оценки компилятора для указанного цикла
Директивы !dir$ языка Fortran¶
Директивы !dir$ для оптимизации кода¶
!dir$
unroll (N)
Применить Loop Unrolling на N к ближайшему после объявления директивы циклу. Дополнительным эффектом применения прагмы является увеличение оценочного количества итераций указанного цикла, если оно не известно точно. Количество итераций вычисляется как
min_ovl * N
, гдеmin_ovl
- минимальное количество итераций, при котором применится оптимизация аппаратного наложения итераций цикла. Для более точного определения количества итераций цикла рекомендуется использовать эту прагму в комбинации с!dir$ loop count (N)
!dir$
loop count (N)
Установить у ближайшего после объявления директивы цикла количество итераций равное N. Игнорируется, если подан реальный профиль через
-fprofile-use
!dir$
vector always
Форсирует применение векторизации к ближайшему после объявления директивы циклу, даже если эвристики оптимизации говорят, что её применение нецелесообразно
!dir$
vector aligned
Говорит компилятору, что все обращения к памяти в ближайшем после объявления директивы цикле являются выровненными, так что векторизация может примениться к этому циклу более эффективно. Величина выравнивания зависит от целевой архитектуры: для Elbrus V1-V4 это 8 байт, для V5 и далее - 16 байт.
!dir$
vector unaligned
Говорит компилятору, что все обращения к памяти в ближайшем после объявления директивы цикле являются невыровненными, поэтому строить динамические проверки выровненности операций обращения к памяти не следует.
!dir$
vector nontemporal
Запрет заведения в кэш-память всех уровней и включение режима write combining (объединение операций в store-буфере) для операций записи в ближайшем после объявления директивы цикле.
!dir$
novectorЗапрет применения векторизации к ближайшему после объявления директивы циклу
!dir$
reduce recurrence
Форсирует разрыв рекурентностей в ближайшем после объявления директивы цикле
!dir$
inlineРекомендует inline-подстановку всех функций в следующую за директивой строку или в тело следующего за директивой цикла. Обычно компилятор игнорирует такие подсказки, однако, вместе с опциями
-finline-only-native
или-fforce-inline
они могут стать более весомыми.
!dir$
forceinlineОбязывает компилятор произвести inline-подстановку всех функций в следующую за директивой строку или в тело следующего за директивой цикла.
!dir$
noinlineЗапрещает компилятору производить inline-подстановку в следующую за директивой строку или в тело следующего за директивой цикла.
!dir$
ivdepУказывает, что в ближайшем после объявления директивы цикле, если для пары операций чтения/записи не удалось статически определить их зависимость или независимость, то следует считать, что межитерационные зависимости для этих операций отсутствуют
!dir$
no_damЗапрещает применение динамического разрыва зависимостей (DAM) к ближайшему после объявления директивы циклу. Может быть полезной в случае, когда в цикле есть maybe-зависимости между операциями доступа к памяти, из-за которых применение DAM приводит к частому уходу на компенсирующий код
!dir$
spmvПозиционирует ближайший цикл как цикл умножения разреженных матриц. Это даёт возможность лучше настроить оптимизации и оценки компилятора для указанного цикла
!dir$
swpФорсирует применение оптимизаций конвейеризации к ближайшему после объявления циклу, выключая проверки эффективности конвейеризации для этого цикла
!dir$
noswpЗапрещает применение оптимизаций конвейеризации к ближайшему после объявления циклу
!dir$
comb_operФорсирует комбинирование пар арифметических операций в двухэтажные операции в ближайшем после объявления директивы цикле, даже если эвристики оптимизации говорят, что это нецелесообразно
!dir$
no_comb_operЗапрещает комбинирование пар арифметических операций в двухэтажные операции в ближайшем после объявления директивы цикле
!dir$
expect_prob P
Задает вероятность перехода на ветку THEN в операторе IF в следующей за директивой строке. Вероятность P должна быть в диапазоне [0..1]. Это позволяет компилятору лучше настроить оптимизации для данного перехода.
Побочные эффекты оптимизационных директив #pragma и !dir$¶
Почти все оптимизационные директивы #pragma
и !dir$
для циклов
приводят к отключению оптимизации Loop Jam
(слияние независимых смежных циклов с одинаковым количеством итераций).
Это вызвано тем, что во многих случаях после слияния циклов невозможно
точно исполнить предписание директив #pragma
и !dir$
.
В число таких директив входят:
#pragma
unroll(N)
#pragma
loop count(N)
#pragma
vector#pragma
novector#pragma
reducerecurrence
#pragma
prefetch#pragma
noprefetch#pragma
comb_oper#pragma
ivdep#pragma
no_dam#pragma
spmv!dir$
unroll(N)
!dir$
loop count(N)
!dir$
vector!dir$
novector!dir$
reducerecurrence
!dir$
comb_oper!dir$
ivdep!dir$
no_dam!dir$
spmv