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