В общем, вы хотите, чтобы размер ваших блоков / сетки соответствовал вашим данным и одновременно максимизировал занятость, то есть количество потоков, активных одновременно. Основными факторами, влияющими на занятость, являются использование разделяемой памяти, использование регистров и размер блока потока.
Графический процессор с поддержкой CUDA имеет свои возможности обработки, разделенные на SM (потоковые мультипроцессоры), а количество SM зависит от фактической карты, но здесь мы сосредоточимся на одном SM для простоты (все они ведут себя одинаково). Каждый SM имеет конечное количество 32-битных регистров, разделяемую память, максимальное количество активных блоков И максимальное количество активных потоков. Эти числа зависят от CC (вычислительной мощности) вашего графического процессора и могут быть найдены в середине статьи Википедии http://en.wikipedia.org/wiki/CUDA.
Прежде всего, размер блока потока всегда должен быть кратен 32, потому что ядра выдают инструкции в виде перекосов (32 потока). Например, если у вас размер блока в 50 потоков, графический процессор по-прежнему будет выдавать команды 64 потокам, и вы просто их тратите.
Во-вторых, прежде чем беспокоиться об общей памяти и регистрах, попробуйте размер ваших блоков на основе максимального количества потоков и блоков, которые соответствуют вычислительным возможностям вашей карты. Иногда есть несколько способов сделать это ... например, карта CC 3.0 на каждом SM может иметь 16 активных блоков и 2048 активных потоков. Это означает, что если у вас 128 потоков на блок, вы можете уместить в SM 16 блоков, прежде чем достигнете предела в 2048 потоков. Если вы используете 256 потоков, вы можете уместить только 8, но вы по-прежнему используете все доступные потоки и по-прежнему будете иметь полную занятость. Однако при использовании 64 потоков на блок будет использоваться только 1024 потока при достижении предела в 16 блоков, поэтому заполнение только 50%. Если использование разделяемой памяти и регистров не является узким местом, это должно быть вашей основной проблемой (кроме размеров данных).
Что касается вашей сетки ... блоки в вашей сетке для начала распределяются по SM, а затем оставшиеся блоки помещаются в конвейер. Блоки перемещаются в SM для обработки, как только в этом SM будет достаточно ресурсов для приема блока. Другими словами, когда блоки завершаются в SM, новые перемещаются внутрь. Вы можете привести аргумент, что блоки меньшего размера (128 вместо 256 в предыдущем примере) могут выполняться быстрее, поскольку особенно медленный блок потребляет меньше ресурсов, но это очень сильно зависит от кода.
Что касается регистров и общей памяти, посмотрите на это дальше, так как это может ограничивать вашу занятость. Общая память ограничена для всего SM, поэтому постарайтесь использовать ее в количестве, позволяющем как можно большему количеству блоков уместиться на SM. То же самое и с регистром. Опять же, эти числа зависят от вычислительных возможностей, и их можно найти в таблице на странице википедии. Удачи!
person
underpickled
schedule
16.10.2012