Я использую CUDA в течение нескольких недель, но у меня есть некоторые сомнения в распределении блоков /warps/thread. Я изучаю архитектуру с дидактической точки зрения (университетский проект), поэтому достижение максимальной производительности не является моей проблемой.
Прежде всего, я хотел бы понять, правильно ли я получил эти факты:
-
Программист записывает ядро и организует его выполнение в сетке блоков потоков.
-
Каждый блок назначается поточному мультипроцессору (SM). После назначения он не может перейти на другой SM.
-
Каждый SM разбивает свои собственные блоки на Warps (в настоящее время с максимальным размером 32 потока). Все потоки в warp выполняются одновременно на ресурсах SM.
-
Фактическое выполнение потока выполняется ядрами CUDA, содержащимися в SM. Нет конкретного сопоставления между потоками и ядрами.
-
Если warp содержит 20 потоков, но в настоящее время доступно только 16 ядер, warp не будет работать.
-
С другой стороны, если блок содержит 48 потоков, он будет разбит на 2 искажения, и они будут выполняться параллельно при условии, что доступно достаточно памяти.
-
Если поток запускается на ядре, он останавливается для доступа к памяти или для длинной операции с плавающей запятой, его выполнение может возобновиться на другом ядре.
Правильны ли они?
Теперь у меня есть GeForce 560 Ti, поэтому в соответствии со спецификациями он оснащен 8 SM, каждый из которых содержит 48 ядер CUDA (всего 384 ядра).
Моя цель - убедиться, что каждое ядро архитектуры выполняет ТОЛЬКО инструкции. Предполагая, что мой код не будет требовать больше регистра, чем те, которые доступны в каждом SM, я представил различные подходы:
-
Я создаю 8 блоков по 48 потоков каждый, так что каждый SM имеет 1 блок для выполнения. В этом случае 48 потоков будут выполняться параллельно в SM (используя все 48 ядер, доступных для них)?
-
Есть ли разница, если я запустил 64 блока из 6 потоков? (Предполагая, что они будут отображаться равномерно среди SM)
-
Если я "погружаю" графический процессор в запланированную работу (например, 1024 кадра из 1024 потоков каждый), разумно предположить, что все ядра будут использоваться в определенной точке и будут выполнять те же вычислений (при условии, что нити никогда не останавливаются)?
-
Есть ли способ проверить эти ситуации с помощью профилировщика?
-
Есть ли ссылки на этот материал? Я прочитал руководство по программированию CUDA и главы, посвященные аппаратной архитектуре в "Программирование многопараллельных процессоров" и "Разработка и разработка приложений CUDA"; но я не мог получить точный ответ.