Поддерживаемые директивы #pragma и !dir$
========================================

.. contents::
   :local:

.. toctree::
   :hidden:

Директивы #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 для управления выравниванием полей структур и классов
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#pragma`` **pack**
| ``#pragma`` **pack** ``(n)``
| ``#pragma`` **pack** ``(push, n)``
| ``#pragma`` **pack** ``(pop)``

Директивы #pragma для для задания идентификационной строки
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#ident "string"``
| ``#pragma`` **ident** ``"string"``

  Игнорируются

Директивы #pragma для работы с именами на уровне ассемблерного текста
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#pragma`` **redefine_extname** ``oldname newname``

  Замена имени С функции ``oldname`` на имя ``newname``, используемое в ассемблере

| ``#pragma`` **weak** ``symbol``
| ``#pragma`` **weak** ``symbol1 = symbol2``

  Объявления имен "слабыми" или "вторыми" для других имен

Директивы #pragma, специфичные для GCC
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#pragma`` **GCC** ``visibility push (<ELF-visibility>)``
| ``#pragma`` **GCC** ``visibility pop``

  Управление видимостью символов

Директивы #pragma стандарта C99
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#pragma`` **STDC** ``FP_CONTRACT [ ON | OFF | DEFAULT ]``
| ``#pragma`` **STDC** ``FENV_ACCESS [ ON | OFF | DEFAULT ]``
| ``#pragma`` **STDC** ``CX_LIMITED_RANGE [ ON | OFF | DEFAULT ]``

| ``#pragma`` **STDC** ``FX_FULL_PRECISION [ ON | OFF | DEFAULT ]``
| ``#pragma`` **STDC** ``FX_FRACT_OVERFLOW [ SAT | DEFAULT ]``
| ``#pragma`` **STDC** ``FX_ACCUM_OVERFLOW [ SAT | DEFAULT ]``

Директивы #pragma для оптимизации кода
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

| ``#pragma`` **omp**

  Управление распараллеливанием с использованием стандарта OpenMP

| ``#pragma`` **asm_inline**
| ``#pragma`` **no_asm_inline**

  Управление inline-подстановкой ассемблерных вставок

| ``#pragma`` **unknown_control_flow** ``(func_name)``

  Обработка функции ``func_name`` аналогично функции ``setjmp``

| ``#pragma`` **no_instrument_function** ``(func_name)``

  Отказ от инструментирования функции ``func_name``

| ``#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``

  Говорит компилятору, что все обращения к памяти в ближайшем после объявления
  директивы цикле являются выровненными, так что векторизация может примениться
  к этому циклу более эффективно

| ``#pragma`` **vector** ``unaligned``

  Говорит компилятору, что все обращения к памяти в ближайшем после объявления
  директивы цикле являются невыровненными (сейчас эта информация игнорируется)

| ``#pragma`` **vector** ``nontemporal``

  Запрет заведения в кэш-память всех уровней и включение режима write combining
  (объединение операций в store-буфере) для операций записи
  в ближайшем после объявления директивы цикле.

| ``#pragma`` **novector**

  Запрет применения векторизации к ближайшему после объявления директивы циклу

| ``#pragma`` **reduce** ``recurrence``

  Форсирует разрыв рекурентностей в ближайшем после объявления директивы цикле

| ``#pragma`` **prefetch**

  Форсирует включение аппаратной предподкачки данных для регулярных операций
  чтения из памяти в ближайшем после объявления директивы цикле, даже если
  эвристики оптимизации говорят, что это нецелесообразно; не влияет на
  автоматическую генерацию операций программной предподкачки

| ``#pragma`` **noprefetch**

  Запрет аппаратной предподкачки данных для регулярных операций чтения из памяти
  в ближайшем после объявления директивы цикле; не влияет на автоматическую
  генерацию операций программной предподкачки

| ``#pragma`` **comb_oper**

  Форсирует комбинирование пар арифметических операций в двухэтажные операции
  в ближайшем после объявления директивы цикле, даже если эвристики оптимизации
  говорят, что это нецелесообразно

| ``#pragma`` **ivdep**

  Указывает, что в ближайшем после объявления директивы цикле, если для пары операций
  чтения/записи не удалось статически определить их зависимость или независимость,
  то следует считать, что межитерационные зависимости для этих операций отсутствуют

| ``#pragma`` **no_dam**

  Запрещает применение динамического разрыва зависимостей (DAM) к ближайшему
  после объявления директивы циклу. Может быть полезной в случае, когда в цикле
  есть maybe-зависимости между операциями доступа к памяти, из-за которых
  применение DAM приводит к частому уходу на компенсирующий код

| ``#pragma`` **inline**

  Рекомендует inline-подстановку функций в следующую за директивой строку.
  Обычно компилятор игнорирует такие подсказки, однако, вместе с опциями
  ``-finline-only-native`` или ``-fforce-inline`` они могут стать более весомыми.

| ``#pragma`` **no_inline**

  Запрещает inline-подстановку функций в следующую за директивой строку

| ``#pragma`` **hot** ``(func_list)``

  Для пометки того, что указанные функции являются "горячими"

| ``#pragma`` **no_side_effect** ``(func_list)``

  Указывает, что функции не имеют посторонних эффектов (не меняют состояние программы,
  невидимое в точке вызова). Игнорируется


Директивы !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** ``nontemporal``
| ``!dir$`` **vector_end** ``nontemporal``

  Запрет заведения в кэш-память всех уровней и включение режима write combining
  (объединение операций в store-буфере) для операций записи в ближайшем после
  объявления директивы цикле.

| ``!dir$`` **inline**

  Рекомендует inline-подстановку всех функций в следующую за директивой строку
  или в тело следующего за директивой цикла. Обычно компилятор игнорирует такие
  подсказки, однако, вместе с опциями ``-finline-only-native`` или ``-fforce-inline`` они
  могут стать более весомыми.

| ``!dir$`` **forceinline**

  Обязывает компилятор произвести inline-подстановку всех функций в следующую за
  директивой строку или в тело следующего за директивой цикла.

| ``!dir$`` **noinline**

  Запрещает компилятору производить inline-подстановку в следующую за директивой
  строку или в тело следующего за директивой цикла.

