2010-12-08 6 views
41

Я новичок в парадигме CUDA. Мой вопрос заключается в определении количества потоков на блок и блоков в сетке. Входит ли в это искусство и испытание? Я обнаружил, что многие примеры имеют, по-видимому, произвольное число, выбранное для этих вещей.CUDA, определяющий потоки на блок, блоки на сетку

Я рассматриваю проблему, когда я мог бы передавать матрицы - любого размера - методу умножения. Таким образом, каждый элемент C (как в C = A * B) будет вычисляться одним потоком. Как бы вы определили потоки/блок, блоки/сетку в этом случае?

ответ

66

В общем, вы хотите, чтобы размер блоков/сетки соответствовал вашим данным и одновременно увеличивал количество занятых, то есть сколько потоков было активным за один раз. Основными факторами, влияющими на занятость, являются использование общей памяти, использование регистров и размер блока потока.

Графический процессор с поддержкой CUDA имеет свои возможности обработки, разделенные на SMs (потоковые мультипроцессоры), а количество SM зависит от реальной карты, но здесь мы сосредоточимся на одном SM для простоты (все они ведут себя одинаково). Каждый SM имеет конечное число 32-битных регистров, разделяемую память, максимальное количество активных блоков и максимальное количество активных потоков. Эти числа зависят от CC (вычислительная способность) вашего GPU и могут быть найдены в середине статьи Википедии http://en.wikipedia.org/wiki/CUDA.

Прежде всего, размер блока потока всегда должен быть кратным 32, потому что ядра выдают инструкции в деформациях (32 потока).Например, если у вас размер блока 50 потоков, GPU по-прежнему выдаст команды для 64 потоков, и вы просто будете их тратить.

Во-вторых, прежде чем беспокоиться об общей памяти и регистрах, попробуйте размер блоков на основе максимального количества потоков и блоков, соответствующих вычислительной способности вашей карты. Иногда есть несколько способов сделать это ... например, карта CC 3.0 каждый SM может иметь 16 активных блоков и 2048 активных потоков. Это означает, что если у вас есть 128 потоков на блок, вы можете поместить 16 блоков в свой SM, прежде чем достигнуть предела потока 2048. Если вы используете 256 потоков, вы можете поместиться только в 8, но вы все еще используете все доступные потоки и по-прежнему будете иметь полное заполнение. Однако при использовании 64 потоков на блок будет использоваться только 1024 потока при ударе по 16 блокам, поэтому только 50% заполняемости. Если разделяемая память и использование регистров не являются узким местом, это должно быть вашей главной проблемой (кроме ваших размеров данных).

По теме вашей сетки ... блоки в вашей сетке распределяются по SM для запуска, а затем остальные блоки помещаются в конвейер. Блоки перемещаются в SM для обработки, как только в этом SM достаточно ресурсов, чтобы взять блок. Другими словами, когда блоки завершены в SM, новые перемещаются. Вы можете сделать аргумент о том, что меньшие блоки (128 вместо 256 в предыдущем примере) могут завершиться быстрее, поскольку особенно медленный блок будет обрабатывать меньше ресурсов, но это очень сильно зависит от кода.

Что касается регистров и разделяемой памяти, посмотрите на следующее, так как это может ограничивать ваше размещение. Общая память ограничена для всего SM, поэтому попробуйте использовать ее в количестве, которое позволяет как можно больше блоков по-прежнему поместиться на SM. То же самое касается использования регистра. Опять же, эти числа зависят от вычислительной способности и могут быть найдены в таблице на странице wikipedia. Удачи!

+0

Почему мы не можем рассчитать блоки/потоки, используя возможности устройства? Предположим, у меня есть устройство с возможностями 2.1 (GT 520), поэтому он имеет 48 SM, по 8 блоков и 1024 потока на блок. Я не могу это получить, извините, если мой вопрос глупо. – greg 2013-07-18 12:30:17

14

За редким исключением вы должны использовать постоянное количество потоков на каждый блок. Затем количество блоков на сетку определяется размером проблемы, например размерами матрицы в случае матричного умножения.

Выбор количества потоков в блоке очень сложный. Большинство алгоритмов CUDA допускают широкий диапазон возможностей, и выбор основан на том, что делает ядро ​​работать наиболее эффективно. Это почти всегда кратно 32 и по меньшей мере 64 из-за того, как работает оборудование планирования потоков. Хороший выбор для первой попытки 128 или 256.

+0

Не могли бы вы дать более подробное объяснение ваших рассуждений о постоянных потоках на блок? (Или даже ссылку на соответствующую статью). Огромное спасибо, – 2018-01-09 17:37:44

16

http://developer.download.nvidia.com/compute/cuda/CUDA_Occupancy_calculator.xls

CUDA Заполняемость Калькулятор позволяет рассчитать многопроцессорных размещение видеочипа с помощью данного ядра CUDA. Многопроцессорное заполнение - это отношение активных перекосов к максимальному числу перекосов, поддерживаемых на многопроцессорном графическом процессоре. Каждый мультипроцессор на устройстве имеет набор N регистров, доступных для использования потоками программ CUDA. Эти регистры являются общим ресурсом, который распределяется между блоками потоков, выполняемыми на мультипроцессоре. Компилятор CUDA пытается минимизировать использование регистров, чтобы максимизировать количество блоков потоков, которые могут быть активны в машине одновременно. Если программа пытается запустить ядро, для которого регистры использовались на каждый поток, размер блока нити больше N, запуск не будет завершен ...

2

Вам также необходимо рассмотреть общую память, поскольку потоки в том же блок может обращаться к одной и той же общей памяти. Если вы разрабатываете что-то, что требует много разделяемой памяти, то больше потоков на блок может быть выгодным.

Например, с точки зрения переключения контекста любое число из 32 работает одинаково. Таким образом, для случая 1D запуск 1 блока с 64 потоками или 2 блока с 32 потоками не имеет никакого значения для доступа к глобальной памяти. Однако, если проблема под рукой, естественно, разлагается на один вектор длиной 64, тогда первый вариант будет лучше (меньше накладных расходов памяти, каждый поток может получить доступ к одной и той же общей памяти), чем второй.

Смежные вопросы