Скажите gcc, чтобы конкретно развернуть цикл - PullRequest
45 голосов
/ 01 ноября 2010

Как я могу сказать GCC развернуть определенный цикл?Я использовал CUDA SDK, где циклы можно развернуть вручную, используя #pragma unroll.Есть ли подобная функция для gcc?Я немного погуглил, но ничего не смог найти.

Ответы [ 3 ]

52 голосов
/ 10 января 2013

GCC дает вам несколько различных способов справиться с этим:

  • Используйте # прагматические директивы , например #pragma GCC optimize ("string"...), как показано в GCC документах . Обратите внимание, что прагма оптимизирует global для остальных функций. Если бы вы умело использовали макросы #pragma push_options и pop_options, вы могли бы определить это только с помощью одной функции, например:

    #pragma GCC push_options
    #pragma GCC optimize ("unroll-loops")
    
    //add 5 to each element of the int array.
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    
    #pragma GCC pop_options
    
  • Аннотируйте отдельные функции с помощью Синтаксис атрибута GCC : проверьте документ Атрибут функции GCC , чтобы получить более подробную диссертацию по этому вопросу. Пример:

    //add 5 to each element of the int array.
    __attribute__((optimize("unroll-loops")))
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    

Примечание: Я не уверен, насколько хорош GCC при развертывании циклов с обратной итерацией (я сделал это, чтобы Markdown хорошо играл с моим кодом). Однако примеры должны хорошо скомпилироваться.

4 голосов
/ 01 ноября 2010

-funroll-loops может быть полезным (хотя это включает глобальное развертывание цикла, а не цикл).Я не уверен, есть ли #pragma, чтобы сделать то же самое ...

3 голосов
/ 22 февраля 2019

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

#pragma GCC unroll n

Цитирование из руководства:

Вы можете использовать эту прагму, чтобы контролировать, сколько раз цикл должен быть развернут.Он должен быть помещен непосредственно перед циклом for, while или do или #pragma GCC ivdep и применяется только к следующему циклу.n является целочисленным константным выражением, определяющим коэффициент развертывания.Значения 0 и 1 блокируют любое развертывание цикла.

...