Я использую CUDA несколько недель, но у меня есть некоторые сомнения по поводу распределения блоков / деформаций / потоков. Я изучаю архитектуру с дидактической точки зрения (университетский проект), поэтому достижение максимальной производительности - не моя забота.
Прежде всего, я хотел бы понять, правильно ли я понял эти факты:
Программист пишет ядро и организует его выполнение в виде сетки блоков потоков.
Каждый блок закреплен за потоковым мультипроцессором (SM). После назначения он не может перейти на другой SM.
Каждый SM разбивает свои блоки на Warps (в настоящее время максимальный размер 32 потока). Все потоки в основе выполняются одновременно на ресурсах SM.
Фактическое выполнение потока выполняется ядрами CUDA, содержащимися в SM. Нет никакого конкретного сопоставления между потоками и ядрами.
Если деформация содержит 20 потоков, но в настоящее время доступно только 16 ядер, деформация не будет выполняться.
С другой стороны, если блок содержит 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»; но я не мог получить точного ответа.
источник
Ответы:
Две из лучших ссылок:
Постараюсь ответить на каждый ваш вопрос.
Программист делит работу на потоки, потоки на блоки потоков и блоки потоков на сетки. Распределитель вычислительной работы выделяет блоки потоков для потоковых мультипроцессоров (SM). Как только блок потока распределяется по SM, ресурсы для блока потока выделяются (деформации и общая память), и потоки делятся на группы по 32 потока, называемые деформациями. Как только варп выделен, он называется активным варпом. Два планировщика деформации выбирают две активные деформации за цикл и отправляют деформации исполнительным единицам. Подробнее о исполнительных единицах и отправке инструкций см. 1 стр.7-10 и 2 .
4 ' . Существует соответствие между laneid (индекс потоков в основе) и ядром.
5 ' . Если деформация содержит менее 32 потоков, она в большинстве случаев будет выполняться так же, как если бы в ней было 32 потока. Деформации могут иметь менее 32 активных потоков по нескольким причинам: количество потоков в блоке не делится на 32, программа выполняет расходящийся блок, поэтому потоки, которые не прошли текущий путь, помечаются как неактивные, или поток в деформации завершился.
6 ' . Блок потока будет разделен на WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize Планировщикам деформации не требуется выбирать две деформации из одного блока потока.
7 ' . Исполнительный модуль не останавливается на операции с памятью. Если ресурс недоступен, когда инструкция готова к отправке, инструкция будет отправлена снова в будущем, когда ресурс станет доступен. Деформации могут останавливаться у барьеров, операций с памятью, операций с текстурами, зависимостей данных и т. Д. Застрявшая деформация не может быть выбрана планировщиком деформации. На Fermi полезно иметь не менее 2 подходящих перекосов за цикл, чтобы планировщик перекосов мог выдать команду.
См. Ссылку 2, чтобы узнать о различиях между GTX480 и GTX560.
Если вы прочитаете справочный материал (несколько минут), я думаю, вы обнаружите, что ваша цель не имеет смысла. Я постараюсь ответить на ваши вопросы.
1 ' . Если вы запустите ядро <<< 8, 48 >>>, вы получите 8 блоков по 2 основы по 32 и 16 потоков. Нет гарантии, что эти 8 блоков будут назначены разным SM. Если SM выделены 2 блока, то возможно, что каждый планировщик деформации может выбрать деформацию и выполнить деформацию. Вы будете использовать только 32 из 48 ядер.
2 ' . Существует большая разница между 8 блоками по 48 потоков и 64 блоками по 6 потоков. Предположим, у вашего ядра нет расхождений, и каждый поток выполняет 10 инструкций.
Для достижения оптимальной эффективности разделение работы должно быть кратным 32 потокам. Аппаратные средства не будут объединять нити с разных основ.
3 ' . GTX560 может иметь 8 блоков SM * 8 = 64 блока за раз или 8 блоков SM * 48 = 512 деформаций, если ядро не исчерпывает максимум регистров или разделяемой памяти. В любой момент времени часть работы будет активна на SM. Каждый SM имеет несколько исполнительных блоков (больше, чем ядер CUDA). Какие ресурсы используются в любой момент времени, зависит от планировщиков деформации и набора команд приложения. Если вы не выполняете операции TEX, модули TEX будут бездействовать. Если вы не выполните специальную операцию с плавающей запятой, блоки SUFU будут бездействовать.
4 ' . Параллельный Nsight и шоу Visual Profiler
а. выполнен IPC
б. выдал МПК
c. активных деформаций за активный цикл
d. подходящие варпы за активный цикл (только Nsight)
е. Причины срыва варпа (только Nsight)
f. активных потоков на выполненную инструкцию
Профилировщик не показывает процент использования любого из исполнительных модулей. Для GTX560 приблизительная оценка будет выдана IPC / MaxIPC. Для MaxIPC предположим, что GF100 (GTX480) - 2, GF10x (GTX560) - 4, но цель - 3 - лучшая цель.
источник
«E. Если варп содержит 20 потоков, но в настоящее время доступно только 16 ядер, варп не будет запущен».
это неверно. Вы сбиваете с толку ядра в их обычном смысле (также используемом в процессорах) - количество «мультипроцессоров» в графическом процессоре с ядрами в маркетинговом выражении nVIDIA («наша карта имеет тысячи ядер CUDA»).
Сама деформация может быть запланирована только на одном ядре (= мультипроцессоре) и может одновременно запускать до 32 потоков; он не может использовать более одного ядра.
Число «48 деформаций» - это максимальное количество активных деформаций (деформаций, которые могут быть выбраны для планирования работы в следующем цикле в любом заданном цикле) на мультипроцессор на графических процессорах NVIDIA с вычислительными возможностями 2.x; и это число соответствует 1536 = 48 x 32 потока.
Ответ на основе этого вебинара
источник