Несколько процессов, запускающих ядра CUDA параллельно

Я знаю, что NVIDIA gpus с вычислительной способностью 2.x или более может одновременно запускать u pto 16 ядер. Однако мое приложение запускает 7 "процессов", и каждый из этих 7 процессов запускает ядра CUDA.

Мой первый вопрос заключается в том, что было бы ожидаемым поведением этих ядер. Будут ли они выполняться одновременно, или, поскольку они запускаются различными процессами, они будут выполняться последовательно.

Я запутался, потому что в руководстве по программированию CUDA C говорится:

"Ядро из одного контекста CUDA не может выполняться одновременно с ядром из другого контекста CUDA". Это подводит меня к моему второму вопросу, каковы CUDA "контексты"?

Спасибо!

Ответ 1

Контекст CUDA - это виртуальное пространство выполнения, которое содержит код и данные, принадлежащие хост-потоку или процессу. Только один контекст может быть активным на графическом процессоре со всем текущим оборудованием.

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

Вам лучше запустить один рабочий поток, содержащий контекст графического процессора, и использовать обмен сообщениями из других потоков, чтобы заставить работать на GPU. В качестве альтернативы доступно средство миграции контекста, доступное в API-интерфейсе драйвера CUDA, но оно будет работать только с потоками одного и того же процесса, а механизм миграции имеет задержку и нагрузку на центральный процессор.

Ответ 2

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

Чтобы выполнить много ядер concrurrenlty, вы должны создать несколько потоков CUDA в одном контексте CUDA и поставить в очередь каждое ядро ​​в свой собственный поток - поэтому они будут выполняться одновременно, если для этого достаточно ресурсов.

Если вам нужно сделать контекст доступным из нескольких потоков ЦП, вы можете использовать cuCtxPopCurrent(), cuCtxPushCurrent(), чтобы передать их, но только один поток сможет работать с контекстом в любое время.

Ответ 3

Добавить к ответу @talonmies

В более новых архитектурах с помощью MPS несколько процессов могут запускать несколько ядер одновременно. Итак, теперь это определенно возможно, чего не было раньше. Для подробного понимания прочитайте эту статью.

https://docs.nvidia.com/deploy/pdf/CUDA_Multi_Process_Service_Overview.pdf

Кроме того, вы также можете увидеть максимальное количество одновременных ядер, разрешенных для каждого типа возможностей cuda compute, поддерживаемых различными графическими процессорами. Вот ссылка на это:

https://en.wikipedia.org/wiki/CUDA#Version_features_and_specifications

Например, на GPU с возможностью вычисления cuda 7.5 может быть запущено максимум 128 ядер Cuda.