CUDA: имеет ли значение количество потоков SM при определении размера блока ядра?

Существует бесчисленное множество статей и вопросов SO, объясняющих, какие размеры сетки и блоков ядра должны быть установлены и как оптимизировать эти значения, но в статьях, похоже, никогда не упоминаются ограничения SM. Насколько я понимаю, SM может выполнять максимум 1536 потоков и максимум 8 блоков. Конечно, эти значения имеют какое-то значение в таких расчетах, так почему бы им не встречаться чаще?

Например. если размер блока моего ядра составляет 128 потоков, то каждый SM будет запускать только 1024 потока из возможных 1536, что является весьма недостаточным использованием.

Или, может быть, это только я, и этот конкретный момент лампочки занял так много времени, в то время как все остальные «просто знают», что нужно учитывать эти вещи!

Эти значения зависят от архитектуры. Серверные ускорители последних поколений имели 2048 потоков на SM, то есть значения даже не одинаковы для всех карт Ampere. Смотрите эту таблицу.

paleonix 29.08.2024 19:14

Различные архитектуры графических процессоров имеют разные ограничения потоков SM. Обычно встречается 1536, но существуют также 1024 и 2048, в зависимости от арх. SM обычно не ограничиваются 8 блоками, не знаю, откуда вы это взяли. В руководстве по программированию есть таблица, охватывающая эти ограничения, не говоря уже о многочисленных публикациях в Интернете. Размер блока 128 не должен вызывать проблем (сам по себе) и может легко заполнить SM на графическом процессоре, независимо от того, имеет ли он предел в 1024, 1536 или 2048. Проблема, на которую я иногда указываю, заключается в том, что 1024 потока на блок будут недостаточно использоваться. SM с лимитом 1536.

Robert Crovella 29.08.2024 19:15

«[Почему] они не возникают чаще?» кажется странным мета-вопросом для SO. Я согласен, что хороший ответ относительно размера блока должен упоминать эти ограничения. Лично я цитирую их, когда сталкиваюсь с людьми, пытающимися использовать очень мало потоков на блок. Одна из причин может заключаться в том, что даже до достижения этих пределов с менее чем 2-3 деформациями на блок часто начинается низкая производительность из-за неэффективного доступа к памяти, учитывая размер страниц памяти (1024 байт). Таким образом, при наличии ядра с привязкой к памяти с линейным шаблоном доступа и доступом 4 байт (8 байт) требуется как минимум 256 (128) потоков на блок.

paleonix 29.08.2024 19:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

tl;dr: Эти цифры появляются не так часто, потому что:

  1. Вы смотрите не на те цифры.
  2. Числа, на которые вы смотрите, очень зависят от микроархитектуры.

Теперь более длинная версия:

Насколько я понимаю, SM может выполнять максимум 1536 потоков и максимум 8 блоков.

Предполагая, что вы имеете в виду графические процессоры NVIDIA с вычислительными возможностями 8,6–8,9, и глядя на таблицу вычислительных возможностей CUDA , мы находим:

Особенность СС 8.6/8.7 КК 8.9 Максимальное количество резидентных блоков на SM 16 24 Максимальное количество резидентных потоков на SM 1536 1536

и я предполагаю, что отсюда у вас получилось число 1536. (Все-таки не 8 блоков на СМ, ​​а 16 или 24).

Тем не менее, если мы посмотрим на вычислительные возможности 8.0, например. на картах А40 это 2048 резидентных потоков, а не 1536; и 32 жилых блока. То же самое касается вычислительных возможностей 9.0. Итак, как написал @RobertCrovella в этом комментарии, это очень зависит от архитектуры.

но - даже если вы исправите микроархитектуру графического процессора - это все равно неправильные цифры!

Максимальный размер блока не равен максимальному количеству потоков, которые могут находиться в SM. Вполне типично, что несколько блоков постоянно находятся в SM, при этом деформации из разных блоков планируются в зависимости от доступности. CUDA всегда (?) определяла максимальный размер блока в 1024 потока — не больше и не меньше, независимо от микроархитектуры.

Что касается максимального размера сетки — это скорее «числовые ограничения». За этим же столом вы найдете:

Максимальный размер x сетки блоков резьбы 231 - 1 Максимальный размер y или z сетки блоков резьбы 65536

Эти максимумы не зависят от размера блока в потоках или от максимального размера блока в потоках. И хотя они в принципе зависят от вашей микроархитектуры (например, NVIDIA могла бы сделать карту, поддерживающую 128К блоков по оси Y сетки) — на практике эти значения не менялись уже много лет.


Note, though, that even if the max number of resident threads is not the relevant number, if you choose a block size which doesn't _divide_ the max-resident-threads, then you will necessarily have some "slack" of potential resident threads you're not using: 1024-thread blocks with 1536 max resident threads means an SM will have either 0 or 1 resident blocks, and never utilize the potential for 512 more threads (= 16 more warps) - as @RobertCrovella mentions. But then again - whoever said you need to have those extra resident warps? Maybe your 1024 threads (= 32 warps) is enough to keep the SM busy? It's possible - depending on how your kernel code utilizes SM resources and how your warps interact.

Другие вопросы по теме

Вычисления графического процессора OpenCL/CUDA со скоростью звука. Любой метод достаточно быстрый, чтобы считывать данные с графического процессора один раз для каждого аудиобуфера? (т.е. минимум ~43 FPS)
ONNXRuntimeError: Ошибка LoadLibrary с ошибкой 126 onnxruntime\capi\onnxruntime_providers_cuda.dll
GlGetTexImage возвращает 0 для текстуры, даже если текстура загружена и правильно заполнена в памяти графического процессора
Пример использования иерархии потоков в CUDA
Как я могу использовать PowerShell для определения активной видеокарты с максимальной емкостью видеопамяти?
Зачем использовать MPS, Time Slicing или MIG, если настройки Nvidia по умолчанию имеют более высокую производительность?
Использование %load_ext cudf.pandas выдает AttributeError
Какова связь между занятостью потоков графического процессора и остановками синхронизации?
Docker-контейнер с CUDA не видит мой графический процессор | WSL2/Убунту/Win10 | nvcc и nvidia-smi работают
Cupy копирует массив numpy в существующий массив устройств