Это не гарантирует этого.Он гарантирует, что все блоки будут резидентными / запланированными на SM.В любом случае, который вы описываете (все блоки потоков, назначенные / запланированные для уникальных SM, или все блоки потоков, назначенные / запланированные для уникальных SM, за исключением 2, которые назначены / запланированы на той же SM), все блоки потоков будут резидентными , т. Е.запланировано на SM с возможностью планирования их деформаций с помощью планировщика деформаций SM.
Это требование совместного проживания для запуска совместной работы сетки.Не требуется, чтобы каждый блок потока был запланирован на уникальный SM.Требуется только, чтобы каждый потокоблок был запланирован, т. Е. Распакован на SM, чтобы его деформации выбирались / планировались планировщиком деформации SM.
Почему 1 потокоблок на эвристический SM гарантирует совместное проживание всех блоков?Потому что в обратном случае запланированы все блоки, кроме 1, при этом (как минимум) 1 SM остается абсолютно «пустым».Планировщик блоков гарантирует, что такое условие не будет сохраняться бесконечно.В конце концов, планировщик блоков не позволит незапланированному последнему оставшемуся блоку назначить его «пустому» SM (или другому SM для обсуждения патологического случая, на который вы указываете, что не исключено правилами планирования блоков CUDA).Без потери общности, мы также можем расширить этот 1-threadblock-unscheduled аргумент, чтобы он был 2 или более незапланированных потоковых блоков с соответствующим количеством пустых SM на машине, без потери достоверности / корректности в этом аргументе (т. Е.планировщик блоков также не позволит этим условиям сохраниться).
Также обратите внимание, хотя и не имеющий прямого отношения к этому вопросу, механизм запуска совместной сетки исключает параллельные ядра для корректности.Для корректности совместно запущенной сетке должно быть разрешено занимать только машину.
В заключение следует отметить, что эвристика 1-threadblock-per-SM проста, понятна и легко кодируется.Это также верно по вышеуказанным причинам (это гарантирует совместное проживание блоков).Однако это не обязательно оптимальный .Руководство по программированию, а также примеры кодов CUDA CG демонстрируют использование API занятости для получения оптимальности (т. Е. Максимального количества запускаемых потоковых блоков, при этом гарантируя совместное проживание).