В каких типах циклов лучше всего использовать директиву #pragma unroll в CUDA?

В CUDA можно разворачивать циклы с помощью директивы #pragma unroll для повышения производительности за счет увеличения параллелизма на уровне инструкций. За #pragma может дополнительно следовать число, указывающее, сколько раз цикл должен быть развёрнут.

К сожалению, документы не дают конкретных указаний о том, когда следует использовать эту директиву. Поскольку небольшие циклы с известным количеством циклов уже развернуты компилятором, следует ли использовать #pragma unroll для более крупных циклов? На малых шлейфах с переменным счетчиком? А как насчет необязательного количества разворотов? Также есть ли рекомендуемая документация о развертывании цикла cuda?


person charis    schedule 04.11.2012    source источник


Ответы (2)


Здесь нет быстрых и жестких правил. Компилятор CUDA имеет как минимум два средства развертывания, по одному внутри интерфейса NVVM или Open64 и один в бэкэнде PTXAS. В общем, они довольно агрессивно развертывают циклы, поэтому я использую #pragma unroll 1 (для предотвращения развертывания) чаще, чем любой другой атрибут развертывания. Причины отключения развертывания цикла двоякие:

(1) Когда петля полностью развернута, давление в регистре может возрасти. Например, индексы в небольших массивах локальной памяти могут стать константами времени компиляции, что позволит компилятору поместить локальные данные в регистры. Полное развертывание также может привести к удлинению базовых блоков, что позволяет более агрессивно планировать текстуры и глобальные загрузки, что может потребовать дополнительных временных переменных и, следовательно, регистров. Повышенное давление в регистре может привести к снижению производительности из-за разбрызгивания регистра.

(2) Частично развернутые циклы обычно требуют определенного объема кода предварительного расчета и очистки для обработки количества циклов, которое не является точным кратным коэффициенту развертывания. Для циклов с коротким числом переходов эти накладные расходы могут свести на нет любой прирост производительности, который можно было бы получить от развернутого цикла, что приведет к снижению производительности после развертывания. Хотя компилятор содержит эвристики для поиска подходящих циклов при этих ограничениях, эвристики не всегда могут обеспечить наилучшее решение.

В редких случаях я обнаружил, что ручное задание более высокого коэффициента развертывания, чем автоматически используемый компилятором, оказывает небольшое положительное влияние на производительность (с типичным приростом в процентах с одной цифрой). Как правило, это случаи кода с интенсивным использованием памяти, где более высокий коэффициент развертывания позволяет более агрессивно планировать глобальные или текстурные загрузки, или очень тесные циклы, связанные с вычислениями, которые выигрывают от минимизации накладных расходов на цикл.

Игра с коэффициентами развертывания — это то, что должно происходить на поздних этапах процесса оптимизации, поскольку значения по умолчанию компилятора охватывают большинство случаев, с которыми можно столкнуться на практике.

person njuffa    schedule 05.11.2012
comment
То есть в основном методом проб и ошибок? У вас есть готовый оптимизированный код, а затем попробуйте развернуть различные циклы, чтобы увидеть, влияет ли это на производительность? Поскольку об увеличении использования регистров из-за развертывания цикла будет сообщать --ptxas-options=-v, не легко ли отследить сброс регистров? - person charis; 05.11.2012
comment
Развертывание цикла может увеличить давление регистра, но не обязательно. Вы можете получить статистику разлива из -Xptxas -v, правильно. Развертывание цикла — лишь одна из многих оптимизаций, известных компилятору, поэтому существует множество сложных взаимодействий, управляемых в основном эвристиками. Эвристика настроена так, чтобы в большинстве случаев делать правильные вещи, поэтому я рекомендую не вмешиваться вручную до самого конца процесса оптимизации. Это относится к оптимизации компиляторов в целом, а не только к компилятору CUDA. - person njuffa; 05.11.2012
comment
@njuffa: Извините, мой мозг был в режиме записи LaTeX. - person einpoklum; 08.04.2017

Это инструмент, который вы можете использовать для развертывания циклов. Особенности того, когда его следует/не следует использовать, будут сильно различаться в зависимости от вашего кода (например, что внутри цикла). На самом деле нет никаких хороших общих советов, кроме как подумать о том, каким будет ваш код в развернутом или свернутом виде, и подумать, будет ли он лучше развернут.

person CrazyCasta    schedule 04.11.2012