Как оптимизировать 2 идентичных ядра с 50% занятостью, которые могут работать одновременно в CUDA? - PullRequest
2 голосов
/ 13 июля 2020

У меня есть 2 идентичных ядра в CUDA, которые сообщают о 50% теоретической занятости и могут работать одновременно. Однако их вызов в разных потоках показывает последовательное выполнение.

Каждый вызов ядра имеет следующие размеры сетки и блока:

Grid(3, 568, 620)
Block(256, 1, 1 )
With 50 registers per thread.

Это приводит к слишком большому количеству потоков на SM и слишком большому количеству регистров на блок.

Следует ли мне сосредоточить свои следующие усилия по оптимизации на уменьшении количества регистров, используемых ядром?

Или имеет смысл разделить сетку на множество меньших сеток, потенциально позволяя чтобы два ядра были выпущены и работали одновременно. Будет ли здесь проблема с количеством регистров в блоке?

Примечание - отчеты deviceQuery:

MAX_REGISTERS_PER_BLOCK 65K
MAX_THREADS_PER_MULTIPROCESSOR 1024
NUMBER_OF_MULTIPROCESSORS 68

1 Ответ

3 голосов
/ 14 июля 2020

У меня есть 2 идентичных ядра в CUDA, которые сообщают о 50% теоретической занятости ...

ОК

... и могут работать одновременно

Это не то, что подразумевает занятость, и это неверно.

50% -ное заполнение не означает, что у вас есть 50% неиспользуемых ресурсов, которые другое ядро ​​может использовать одновременно. Это означает, что ваш код исчерпал ресурс при выполнении 50% от максимального теоретического количества одновременных варпов. Если вы исчерпали ресурс, вы не можете больше запускать деформации, будь они из этого ядра или любого другого.

Однако их вызов в разных потоках показывает последовательное выполнение.

Именно этого и следовало ожидать по причинам, указанным выше

Каждый вызов ядра имеет следующие размеры сетки и блока:

Grid(3, 568, 620)
Block(256, 1, 1 )
With 50 registers per thread.

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

Это приводит к слишком большому количеству потоков на SM и слишком много регистров в блоке.

Давление на регистры, вероятно, ограничивает занятость

Следует ли мне сосредоточить свои следующие усилия по оптимизации на уменьшении количества регистров, используемых ядро?

Учитывая, что цель одновременного выполнения ядра невозможна, я думаю, что цель должна состоять в том, чтобы заставить это ядро ​​работать как можно быстрее. Как это сделать, указано в коде c. В некоторых случаях оптимизация регистров может увеличить занятость и производительность, но иногда все, что происходит, - это утечка в локальную память, которая снижает производительность.

Или имеет смысл разделить сетку на множество меньших сеток, потенциально позволяя запускать и запускать 2 ядра одновременно.

Когда вы говорите «много», вы подразумеваете тысячи сеток, и это будет означать такую ​​большую задержку запуска и планирования, что я мог бы не представляю себе никакой пользы от этого, если бы вы смогли добраться до точки, где было возможно одновременное выполнение ядра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...