Вдруг кто-нибудь из читателей этот вопрос уже проходил?
В CUDA параллельная программа запускается в виде множества тредов. Треды логически группируются в блоки, а блоки – в гриды. Треды внутри одного блока имеют доступ к общей быстрой памяти и могут синхронизироваться, а треды из разных блоков могут общаться только через медленную память и не имеют встроенных средств синхронизации.
При запуске можно указать количество тредов на блок и блоков на грид, причем это количество может быть не только скаляром, а ещё и 2- или 3-мерным вектором.
Физически треды выполняются на thread processor’ах, блоки – на мультипроцессорах (каждый мультипроцессор обычно содержит 8 thread processor’ов, один блок вычислений с плавающей точкой с двойной точностью и быструю общую память, доступную только изнутри этого мультипроцессора).
А грид выполняется на всём GPU, содержащем N мультипроцессоров (например, 10).
Собственно вопрос: если задача по сути линейная (скажем, тупой перебор ключей шифрования), и тредам вообще не нужна синхронизация и обмен данными между собой, то какими следует выбирать размеры блока и грида для достижения максимального быстродействия?
Или где про это можно почитать?
Upd: на первый взгляд логично тредов делать ровно столько, сколько может физически одновременно выполнить GPU: размер блока сделать равным количеству thread processor’ов в мультипроцессоре, а размер грида равным количеству мультипроцессоров.
Но есть ещё перенос расчётных данных из основной системы в GPU и обратно, и я сильно подозреваю, что один перенос большой порции будет быстрее, чем несколько раз меньшими частями. Если это так, то лучше сразу тредов сделать побольше и передать им всем данные за один присест. Но это вызовет накладные расходы на переключение тредов, и хотя декларируется, что в GPU это операция малозатратная, но всё же ненулевая.
Оригинал этой записи. Комментировать можно тут или там.
Любые материалы из этого блога запрещается использовать на сайте livejournal.ru в любой форме и любом объёме