создание контекста cuda и ассоциация ресурсов в приложениях API времени выполнения - PullRequest
6 голосов
/ 24 сентября 2011

Я хочу понять, как контекст cuda создается и ассоциируется с ядром в приложениях API времени выполнения cuda?

Я знаю, что это делается под капотом API драйверов. Но я хотел бы понять сроки создания.

Для начала я знаю, что cudaRegisterFatBinary - это первый вызов cuda api, который регистрирует файл fatbin во время выполнения. За ним следует несколько API-интерфейсов регистрации функций cuda, которые вызывают cuModuleLoad на уровне драйверов. Но затем, если мое приложение API времени выполнения Cuda вызывает cudaMalloc, как указатель на эту функцию связан с контекстом, который, я считаю, должен был быть создан заранее. Как получить дескриптор этого уже созданного контекста и связать с ним будущие вызовы API времени выполнения? Пожалуйста, демистифицируйте внутреннюю работу.

Цитировать документацию NVIDIA по этому вопросу

Вызовы API CUDA Runtime работают с CUcontext API драйвера CUDA, который привязан к текущему хост-потоку.

Если не существует API-интерфейса драйвера CUDA, CUcontext привязывается к текущему поток во время вызова API CUDA Runtime, который требует CUcontext затем CUDA Runtime неявно создаст новый CUcontext перед выполнением вызова.

Если среда выполнения CUDA создает CUcontext, тогда CUcontext будет созданный с использованием параметров, указанных в CUDA Runtime API функции cudaSetDevice, cudaSetValidDevices, cudaSetDeviceFlags, cudaGLSetGLDevice, cudaD3D9SetDirect3DDevice, cudaD3D10SetDirect3DDevice и cudaD3D11SetDirect3DDevice. Обратите внимание, что эти функции завершатся с cudaErrorSetOnActiveProcess, если они вызывается, когда CUcontext привязан к текущему хост-потоку.

Время жизни CUcontext управляется подсчетом ссылок механизм. Счетчик ссылок CUcontext изначально установлен на 0, и увеличивается на cuCtxAttach и уменьшается на cuCtxDetach.

Если CUcontext создается средой выполнения CUDA, то среда выполнения CUDA уменьшит счетчик ссылок CUcontext в функции cudaThreadExit. Если CUcontext создается с помощью API драйвера CUDA (или создается отдельным экземпляром библиотеки CUDA Runtime API), тогда CUDA Runtime не будет увеличивать или уменьшать ссылку количество этого CUcontext.

Все состояние CUDA Runtime API (например, адреса глобальных переменных и значения) путешествует с его базовым CUcontext. В частности, если CUcontext перемещается из одного потока в другой (с использованием cuCtxPopCurrent и cuCtxPushCurrent) тогда все состояние API CUDA Runtime будет перемещено в эта нить также.

Но что я не понимаю, так это как среда выполнения cuda создает контекст? какие вызовы API используются для этого? Компилятор nvcc вставляет некоторые вызовы API, чтобы сделать это во время компиляции, или это делается полностью во время выполнения? Если первое верно, какие API времени выполнения используются для этого управления контекстом? Это правда позже, как именно это сделано?

Если контекст связан с хост-потоком, как мы можем получить доступ к этому контексту? Связывается ли оно автоматически со всеми переменными и ссылками на указатели, обрабатываемыми потоком?

как в конечном итоге происходит загрузка модуля в контексте?

1 Ответ

3 голосов
/ 24 сентября 2011

Среда выполнения CUDA поддерживает глобальный список загружаемых модулей и добавляет в этот список каждый раз, когда в процесс загружается DLL или .so, которые используют среду выполнения CUDA.Но модули фактически не загружаются до тех пор, пока не будет создано устройство.

Создание и инициализация контекста выполняется «лениво» средой выполнения CUDA - каждый раз, когда вы вызываете функцию, подобную cudaMemcpy (), она проверяет, является лиCUDA была инициализирована, и если нет, она создает контекст (на устройстве, ранее указанном cudaSetDevice (), или устройство по умолчанию, если cudaSetDevice () никогда не вызывался), и загружает все модули.С этого момента контекст ассоциируется с этим потоком ЦП, пока он не будет изменен с помощью cudaSetDevice ().

Вы можете использовать функции управления контекстом / потоком из API драйвера, такие как cuCtxPopCurrent () / cuCtxPushCurrent (), дляиспользовать контекст из другого потока.

Вы можете вызвать cudaFree (0);заставить эту ленивую инициализацию произойти.

Я бы настоятельно рекомендовал сделать это во время инициализации приложения, чтобы избежать условий гонки и неопределенного поведения.Продолжайте перечислять и инициализировать устройства как можно раньше в вашем приложении;Как только это будет сделано, в CUDA 4.0 вы можете вызвать cudaSetDevice () из любого потока ЦП, и он выберет соответствующий контекст, созданный вашим кодом инициализации.

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