Развертывание петель в ядрах Metal

Мне нужно заставить компилятор Metal развернуть цикл в моей функции вычисления ядра. До сих пор я пытался поставить #pragma unroll(num_times) перед for циклом, но компилятор игнорирует этот оператор.

Кажется, что компилятор не разворачивает циклы автоматически - я сравнил время выполнения для 1) кода с for циклом 2) того же кода, но с циклом, развернутым вручную. Развернутая вручную версия была в 3 раза быстрее.

Например: я хочу уйти от этого:

for (int i=0; i<3; i++) {
    do_stuff();
}

к этому:

do_stuff();
do_stuff();
do_stuff();

Есть ли вообще что-то вроде разворачивания цикла в языке Metal C ++? Если да, как я могу сообщить компилятору, что я хочу развернуть цикл?


person sarasvati    schedule 20.12.2016    source источник


Ответы (1)


Metal - это подмножество C ++ 11, и вы можете попробовать использовать метапрограммирование шаблонов для развертывания циклов. Следующее скомпилировано в металле, хотя у меня нет времени как следует его протестировать:

template <unsigned N> struct unroll {

    template<class F>
    static void call(F f) {
        f();
        unroll<N-1>::call(f);
    }
};

template <> struct unroll<0u> {

    template<class F>
    static void call(F f) {}
};

kernel void test() {

    unroll<3>::call(do_stuff);

}

Пожалуйста, дайте мне знать, если это сработает! Возможно, вам придется добавить несколько аргументов в call, чтобы передать аргументы в do_stuff.

См. Также: Саморазвертывающийся цикл макросов в C / C ++

person Taylor    schedule 05.01.2017