Здесь нет быстрых и жестких правил. Компилятор CUDA имеет как минимум два средства развертывания, по одному внутри интерфейса NVVM или Open64 и один в бэкэнде PTXAS. В общем, они довольно агрессивно развертывают циклы, поэтому я использую #pragma unroll 1
(для предотвращения развертывания) чаще, чем любой другой атрибут развертывания. Причины отключения развертывания цикла двоякие:
(1) Когда петля полностью развернута, давление в регистре может возрасти. Например, индексы в небольших массивах локальной памяти могут стать константами времени компиляции, что позволит компилятору поместить локальные данные в регистры. Полное развертывание также может привести к удлинению базовых блоков, что позволяет более агрессивно планировать текстуры и глобальные загрузки, что может потребовать дополнительных временных переменных и, следовательно, регистров. Повышенное давление в регистре может привести к снижению производительности из-за разбрызгивания регистра.
(2) Частично развернутые циклы обычно требуют определенного объема кода предварительного расчета и очистки для обработки количества циклов, которое не является точным кратным коэффициенту развертывания. Для циклов с коротким числом переходов эти накладные расходы могут свести на нет любой прирост производительности, который можно было бы получить от развернутого цикла, что приведет к снижению производительности после развертывания. Хотя компилятор содержит эвристики для поиска подходящих циклов при этих ограничениях, эвристики не всегда могут обеспечить наилучшее решение.
В редких случаях я обнаружил, что ручное задание более высокого коэффициента развертывания, чем автоматически используемый компилятором, оказывает небольшое положительное влияние на производительность (с типичным приростом в процентах с одной цифрой). Как правило, это случаи кода с интенсивным использованием памяти, где более высокий коэффициент развертывания позволяет более агрессивно планировать глобальные или текстурные загрузки, или очень тесные циклы, связанные с вычислениями, которые выигрывают от минимизации накладных расходов на цикл.
Игра с коэффициентами развертывания — это то, что должно происходить на поздних этапах процесса оптимизации, поскольку значения по умолчанию компилятора охватывают большинство случаев, с которыми можно столкнуться на практике.
person
njuffa
schedule
05.11.2012