6.7. 外部资源互操作性

本节介绍CUDA运行时应用程序编程接口的外部资源互操作功能。

Functions

__host__cudaError_t cudaDestroyExternalMemory ( cudaExternalMemory_t extMem )
Destroys an external memory object.
__host__cudaError_t cudaDestroyExternalSemaphore ( cudaExternalSemaphore_t extSem )
Destroys an external semaphore.
__host__cudaError_t cudaExternalMemoryGetMappedBuffer ( void** devPtr, cudaExternalMemory_t extMem, const cudaExternalMemoryBufferDesc* bufferDesc )
Maps a buffer onto an imported memory object.
__host__cudaError_t cudaExternalMemoryGetMappedMipmappedArray ( cudaMipmappedArray_t* mipmap, cudaExternalMemory_t extMem, const cudaExternalMemoryMipmappedArrayDesc* mipmapDesc )
Maps a CUDA mipmapped array onto an external memory object.
__host__cudaError_t cudaImportExternalMemory ( cudaExternalMemory_t* extMem_out, const cudaExternalMemoryHandleDesc* memHandleDesc )
Imports an external memory object.
__host__cudaError_t cudaImportExternalSemaphore ( cudaExternalSemaphore_t* extSem_out, const cudaExternalSemaphoreHandleDesc* semHandleDesc )
Imports an external semaphore.
__host__cudaError_t cudaSignalExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreSignalParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
Signals a set of external semaphore objects.
__host__cudaError_t cudaWaitExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreWaitParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
Waits on a set of external semaphore objects.

Functions

__host__cudaError_t cudaDestroyExternalMemory ( cudaExternalMemory_t extMem )
销毁一个外部内存对象。
参数
extMem
- External memory object to be destroyed
描述

销毁指定的外部内存对象。任何已映射到此对象的现有缓冲区和CUDA mipmapped数组必须停止使用,并必须分别使用cudaFreecudaFreeMipmappedArray显式释放。

Note:

另请参阅:

cudaImportExternalMemory, cudaExternalMemoryGetMappedBuffer, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaDestroyExternalSemaphore ( cudaExternalSemaphore_t extSem )
销毁一个外部信号量。
参数
extSem
- External semaphore to be destroyed
描述

销毁一个外部信号量对象并释放对底层资源的任何引用。在销毁信号量之前,所有未完成的信号或等待操作必须已完成。

Note:

另请参阅:

cudaImportExternalSemaphore, cudaSignalExternalSemaphoresAsync, cudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaExternalMemoryGetMappedBuffer ( void** devPtr, cudaExternalMemory_t extMem, const cudaExternalMemoryBufferDesc* bufferDesc )
将缓冲区映射到导入的内存对象上。
参数
devPtr
- Returned device pointer to buffer
extMem
- Handle to external memory object
bufferDesc
- Buffer descriptor
描述

将缓冲区映射到导入的内存对象上,并在devPtr中返回设备指针。

被映射缓冲区的属性必须在bufferDesc中描述。cudaExternalMemoryBufferDesc结构定义如下:

‎        typedef struct cudaExternalMemoryBufferDesc_st {
                  unsigned long long offset;
                  unsigned long long size;
                  unsigned int flags;
              } cudaExternalMemoryBufferDesc;

其中cudaExternalMemoryBufferDesc::offset表示内存对象中缓冲区基地址的偏移量。cudaExternalMemoryBufferDesc::size表示缓冲区的大小。cudaExternalMemoryBufferDesc::flags必须为零。

偏移量和大小必须适当对齐以满足外部API的要求。映射两个范围重叠的缓冲区可能会导致重叠部分返回相同的虚拟地址,也可能不会。在这种情况下,应用程序必须确保GPU对该区域的所有访问都是易失性的。否则,即使是由同一线程发出的写入操作,也不能保证通过一个地址进行的写入能通过另一个地址可见。建议应用程序映射合并后的范围,而不是单独映射缓冲区,然后对返回的指针应用适当的偏移量来获取各个缓冲区。

返回的指针devPtr必须使用cudaFree释放。

Note:

另请参阅:

cudaImportExternalMemory, cudaDestroyExternalMemory, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaExternalMemoryGetMappedMipmappedArray ( cudaMipmappedArray_t* mipmap, cudaExternalMemory_t extMem, const cudaExternalMemoryMipmappedArrayDesc* mipmapDesc )
将CUDA的mipmapped数组映射到外部内存对象上。
参数
mipmap
- Returned CUDA mipmapped array
extMem
- Handle to external memory object
mipmapDesc
- CUDA array descriptor
描述

将CUDA的mipmapped数组映射到一个外部对象,并在mipmap中返回其句柄。

要映射的CUDA mipmapped数组属性必须在mipmapDesc中描述。结构体cudaExternalMemoryMipmappedArrayDesc定义如下:

‎        typedef struct cudaExternalMemoryMipmappedArrayDesc_st {
                  unsigned long long offset;
                  cudaChannelFormatDesc formatDesc;
                  cudaExtent extent;
                  unsigned int flags;
                  unsigned int numLevels;
              } cudaExternalMemoryMipmappedArrayDesc;

其中cudaExternalMemoryMipmappedArrayDesc::offset表示mipmap链基础层在内存对象中的偏移量。cudaExternalMemoryMipmappedArrayDesc::formatDesc描述数据格式。cudaExternalMemoryMipmappedArrayDesc::extent指定mipmap链基础层的维度。cudaExternalMemoryMipmappedArrayDesc::flags是与CUDA mipmapped数组关联的标志位。更多细节请参阅cudaMalloc3DArray文档。请注意,如果mipmapped数组在图形API中被绑定为颜色目标,则必须在cudaExternalMemoryMipmappedArrayDesc::flags中指定cudaArrayColorAttachment标志。cudaExternalMemoryMipmappedArrayDesc::numLevels指定mipmap链中的总层级数。

返回的CUDA mipmapped数组必须使用cudaFreeMipmappedArray释放。

Note:

另请参阅:

cudaImportExternalMemory, cudaDestroyExternalMemory, cudaExternalMemoryGetMappedBuffer

__host__cudaError_t cudaImportExternalMemory ( cudaExternalMemory_t* extMem_out, const cudaExternalMemoryHandleDesc* memHandleDesc )
导入外部内存对象。
参数
extMem_out
- Returned handle to an external memory object
memHandleDesc
- Memory import handle descriptor
描述

导入一个外部分配的内存对象,并在extMem_out中返回该对象的句柄。

导入句柄的属性必须在memHandleDesc中描述。cudaExternalMemoryHandleDesc结构定义如下:

‎        typedef struct cudaExternalMemoryHandleDesc_st {
                  cudaExternalMemoryHandleType type;
                  union {
                      int fd;
                      struct {
                          void *handle;
                          const void *name;
                      } win32;
                      const void *nvSciBufObject;
                  } handle;
                  unsigned long long size;
                  unsigned int flags;
              } cudaExternalMemoryHandleDesc;

其中cudaExternalMemoryHandleDesc::type指定了要导入的句柄类型。cudaExternalMemoryHandleType定义为:

‎        typedef enum cudaExternalMemoryHandleType_enum {
                  cudaExternalMemoryHandleTypeOpaqueFd         = 1,
                  cudaExternalMemoryHandleTypeOpaqueWin32      = 2,
                  cudaExternalMemoryHandleTypeOpaqueWin32Kmt   = 3,
                  cudaExternalMemoryHandleTypeD3D12Heap        = 4,
                  cudaExternalMemoryHandleTypeD3D12Resource    = 5,
                  cudaExternalMemoryHandleTypeD3D11Resource    = 6,
                  cudaExternalMemoryHandleTypeD3D11ResourceKmt = 7,
                  cudaExternalMemoryHandleTypeNvSciBuf         = 8
              } cudaExternalMemoryHandleType;

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeOpaqueFd,那么cudaExternalMemoryHandleDesc::handle::fd必须是一个引用内存对象的有效文件描述符。当该句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作将导致未定义行为。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeOpaqueWin32,那么cudaExternalMemoryHandleDesc::handle::win32::handle和cudaExternalMemoryHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalMemoryHandleDesc::handle::win32::handle不为NULL,则它必须代表一个有效的共享NT句柄,该句柄引用内存对象。导入操作后,该句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果cudaExternalMemoryHandleDesc::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用内存对象。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeOpaqueWin32Kmt,那么cudaExternalMemoryHandleDesc::handle::win32::handle必须非空且cudaExternalMemoryHandleDesc::handle::win32::name必须为空。指定的句柄必须是全局共享的KMT句柄。该句柄不会持有对底层对象的引用,因此当所有对该内存对象的引用被销毁时,该句柄将失效。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeD3D12Heap,那么cudaExternalMemoryHandleDesc::handle::win32::handle和cudaExternalMemoryHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalMemoryHandleDesc::handle::win32::handle不为NULL,则它必须表示一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Heap对象时返回。此句柄持有对底层对象的引用。如果cudaExternalMemoryHandleDesc::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D12Heap对象。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeD3D12Resource,那么cudaExternalMemoryHandleDesc::handle::win32::handle和cudaExternalMemoryHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalMemoryHandleDesc::handle::win32::handle不为NULL,则它必须表示一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Resource对象时返回。此句柄持有对底层对象的引用。如果cudaExternalMemoryHandleDesc::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D12Resource对象。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeD3D11Resource,那么cudaExternalMemoryHandleDesc::handle::win32::handle和cudaExternalMemoryHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalMemoryHandleDesc::handle::win32::handle不为NULL,则它必须表示一个有效的共享NT句柄,该句柄由IDXGIResource1::CreateSharedHandle在引用ID3D11Resource对象时返回。如果cudaExternalMemoryHandleDesc::handle::win32::name不为NULL,则它必须指向一个以NULL结尾的UTF-16字符数组,该数组引用一个ID3D11Resource对象。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeD3D11ResourceKmt,那么cudaExternalMemoryHandleDesc::handle::win32::handle必须为非NULL值,且cudaExternalMemoryHandleDesc::handle::win32::name必须为NULL。指定的句柄必须是由IDXGIResource::GetSharedHandle返回的有效共享KMT句柄,且该句柄指向ID3D11Resource对象。

如果cudaExternalMemoryHandleDesc::typecudaExternalMemoryHandleTypeNvSciBuf,那么cudaExternalMemoryHandleDesc::handle::nvSciBufObject必须为非空并引用有效的NvSciBuf对象。如果导入到CUDA的NvSciBuf对象也被其他驱动程序映射,则应用程序必须使用cudaWaitExternalSemaphoresAsynccudaSignalExternalSemaphoresAsync作为适当的屏障,以保持CUDA与其他驱动程序之间的数据一致性。有关内存同步的信息,请参阅cudaExternalSemaphoreWaitSkipNvSciBufMemSynccudaExternalSemaphoreSignalSkipNvSciBufMemSync

内存对象的大小必须在cudaExternalMemoryHandleDesc::size中指定。

cudaExternalMemoryHandleDesc::flags中指定标志cudaExternalMemoryDedicated表示该资源是专用资源。专用资源的定义不在本扩展范围内。如果cudaExternalMemoryHandleDesc::type是以下类型之一,则必须设置此标志:cudaExternalMemoryHandleTypeD3D12ResourcecudaExternalMemoryHandleTypeD3D11ResourcecudaExternalMemoryHandleTypeD3D11ResourceKmt

Note:
  • 请注意,此函数也可能返回之前异步启动的错误代码。

  • 请注意,如果此调用尝试初始化CUDA RT内部状态,该函数也可能返回cudaErrorInitializationErrorcudaErrorInsufficientDrivercudaErrorNoDevice

  • 请注意,根据cudaStreamAddCallback的规定,回调函数中不得调用任何CUDA函数。在这种情况下,可能会(但不保证)返回cudaErrorNotPermitted作为诊断信息。

  • 如果导入到CUDA的Vulkan内存被映射到CPU上,应用程序必须使用vkInvalidateMappedMemoryRanges/vkFlushMappedMemoryRanges以及适当的Vulkan管线屏障来维护CPU和GPU之间的数据一致性。有关这些API的更多信息,请参阅Vulkan规范中的"同步与缓存控制"章节。

另请参阅:

cudaDestroyExternalMemory, cudaExternalMemoryGetMappedBuffer, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaImportExternalSemaphore ( cudaExternalSemaphore_t* extSem_out, const cudaExternalSemaphoreHandleDesc* semHandleDesc )
导入外部信号量。
参数
extSem_out
- Returned handle to an external semaphore
semHandleDesc
- Semaphore import handle descriptor
描述

导入一个外部分配同步对象,并在extSem_out中返回其句柄。

要导入的句柄属性必须在semHandleDesc中描述。cudaExternalSemaphoreHandleDesc定义如下:

‎        typedef struct cudaExternalSemaphoreHandleDesc_st {
                  cudaExternalSemaphoreHandleType type;
                  union {
                      int fd;
                      struct {
                          void *handle;
                          const void *name;
                      } win32;
                      const void* NvSciSyncObj;
                  } handle;
                  unsigned int flags;
              } cudaExternalSemaphoreHandleDesc;

其中cudaExternalSemaphoreHandleDesc::type指定了要导入的句柄类型。cudaExternalSemaphoreHandleType定义为:

‎        typedef enum cudaExternalSemaphoreHandleType_enum {
                  cudaExternalSemaphoreHandleTypeOpaqueFd                = 1,
                  cudaExternalSemaphoreHandleTypeOpaqueWin32             = 2,
                  cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt          = 3,
                  cudaExternalSemaphoreHandleTypeD3D12Fence              = 4,
                  cudaExternalSemaphoreHandleTypeD3D11Fence              = 5,
                  cudaExternalSemaphoreHandleTypeNvSciSync               = 6,
                  cudaExternalSemaphoreHandleTypeKeyedMutex              = 7,
                  cudaExternalSemaphoreHandleTypeKeyedMutexKmt           = 8,
                  cudaExternalSemaphoreHandleTypeTimelineSemaphoreFd     = 9,
                  cudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32  = 10
              } cudaExternalSemaphoreHandleType;

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeOpaqueFd,那么cudaExternalSemaphoreHandleDesc::handle::fd必须是一个引用同步对象的有效文件描述符。当句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作都会导致未定义行为。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeOpaqueWin32,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle和cudaExternalSemaphoreHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalSemaphoreHandleDesc::handle::win32::handle不为NULL,则它必须引用一个有效的共享NT句柄,该句柄指向同步对象。导入操作后,该句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果cudaExternalSemaphoreHandleDesc::handle::win32::name不为NULL,则它必须命名一个有效的同步对象。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeOpaqueWin32Kmt,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle必须为非NULL且cudaExternalSemaphoreHandleDesc::handle::win32::name必须为NULL。指定的句柄必须是全局共享的KMT句柄。该句柄不会持有对底层对象的引用,因此当所有对该同步对象的引用被销毁时,该句柄将失效。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeD3D12Fence,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle和cudaExternalSemaphoreHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalSemaphoreHandleDesc::handle::win32::handle不为NULL,则它必须表示一个有效的共享NT句柄,该句柄由ID3D12Device::CreateSharedHandle在引用ID3D12Fence对象时返回。此句柄持有对底层对象的引用。如果cudaExternalSemaphoreHandleDesc::handle::win32::name不为NULL,则它必须命名一个有效的同步对象,该对象引用一个有效的ID3D12Fence对象。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeD3D11Fence,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle和cudaExternalSemaphoreHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalSemaphoreHandleDesc::handle::win32::handle不为NULL,则它必须表示由ID3D11Fence::CreateSharedHandle返回的有效共享NT句柄。如果cudaExternalSemaphoreHandleDesc::handle::win32::name不为NULL,则它必须命名一个有效的同步对象,该对象引用有效的ID3D11Fence对象。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeNvSciSync,那么cudaExternalSemaphoreHandleDesc::handle::nvSciSyncObj表示一个有效的NvSciSyncObj。

cudaExternalSemaphoreHandleTypeKeyedMutex,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle和cudaExternalSemaphoreHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalSemaphoreHandleDesc::handle::win32::handle不为NULL,则它表示一个有效的共享NT句柄,该句柄由IDXGIResource1::CreateSharedHandle在引用IDXGIKeyedMutex对象时返回。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeKeyedMutexKmt,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle必须为非NULL值,且cudaExternalSemaphoreHandleDesc::handle::win32::name必须为NULL。指定的句柄必须代表一个有效的KMT句柄,该句柄由IDXGIResource::GetSharedHandle在引用IDXGIKeyedMutex对象时返回。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeTimelineSemaphoreFd,那么cudaExternalSemaphoreHandleDesc::handle::fd必须是一个引用同步对象的有效文件描述符。当句柄成功导入时,文件描述符的所有权将转移给CUDA驱动程序。在导入后对文件描述符执行任何操作都会导致未定义行为。

如果cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32,那么cudaExternalSemaphoreHandleDesc::handle::win32::handle和cudaExternalSemaphoreHandleDesc::handle::win32::name中必须有一个不为NULL。如果cudaExternalSemaphoreHandleDesc::handle::win32::handle不为NULL,则它必须代表一个有效的共享NT句柄,该句柄引用一个同步对象。导入操作后,该句柄的所有权不会转移给CUDA,因此应用程序必须使用适当的系统调用来释放该句柄。如果cudaExternalSemaphoreHandleDesc::handle::win32::name不为NULL,则它必须命名一个有效的同步对象。

Note:

另请参阅:

cudaDestroyExternalSemaphore, cudaSignalExternalSemaphoresAsync, cudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaSignalExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreSignalParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
发送一组外部信号量对象的信号。
参数
extSemArray
- Set of external semaphores to be signaled
paramsArray
- Array of semaphore parameters
numExtSems
- Number of semaphores to signal
stream
- Stream to enqueue the signal operations in
描述

在指定流中对一组外部分配的信号量对象执行信号操作入队。当流中所有先前操作完成后,这些操作将被执行。

信号量的精确语义取决于对象的类型。

如果信号量对象是以下任一类型:cudaExternalSemaphoreHandleTypeOpaqueFdcudaExternalSemaphoreHandleTypeOpaqueWin32cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt,那么触发信号量会将其设置为已触发状态。

如果信号量对象是以下任意一种类型:cudaExternalSemaphoreHandleTypeD3D12FencecudaExternalSemaphoreHandleTypeD3D11FencecudaExternalSemaphoreHandleTypeTimelineSemaphoreFdcudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32,则该信号量将被设置为cudaExternalSemaphoreSignalParams::params::fence::value中指定的值。

如果信号量对象类型为cudaExternalSemaphoreHandleTypeNvSciSync,此API会将cudaExternalSemaphoreSignalParams::params::nvSciSync::fence设置为一个值,该值可被同一NvSciSync对象的后续等待者用于对stream中当前提交的操作进行排序。此类更新将覆盖cudaExternalSemaphoreSignalParams::params::nvSciSync::fence的先前内容。默认情况下,触发此类外部信号量对象会导致对所有导入为cudaExternalMemoryHandleTypeNvSciBuf的外部内存对象执行适当的内存同步操作。这确保了同一组NvSciBuf内存对象的其他导入者进行的后续访问具有一致性。通过指定标志cudaExternalSemaphoreSignalSkipNvSciBufMemSync可以跳过这些操作,当不需要数据一致性时可用作性能优化。但在需要数据一致性的场景下指定此标志将导致未定义行为。此外,对于类型为cudaExternalSemaphoreHandleTypeNvSciSync的信号量对象,如果用于创建NvSciSyncObj的NvSciSyncAttrList未在cudaDeviceGetNvSciSyncAttributes中将标志设置为cudaNvSciSyncAttrSignal,此API将返回cudaErrorNotSupported。

与类型为cudaExternalSemaphoreHandleTypeNvSciSync的信号量对象关联的cudaExternalSemaphoreSignalParams::params::nvSciSync::fence可以是确定性的。为此,用于创建信号量对象的NvSciSyncAttrList必须将NvSciSyncAttrKey_RequireDeterministicFences键的值设置为true。确定性围栏允许用户在对应该信号的操作入队之前就对信号量对象进行等待入队。对于这样的信号量对象,CUDA保证每个信号操作将使围栏值递增'1'。用户需要跟踪信号量对象上入队的信号数量,并相应地插入等待。当这样的信号量对象从多个流中被信号通知时,由于流的并发执行,信号量被信号通知的顺序可能是不确定的。这可能导致信号量的等待者被错误地解除阻塞。用户需要处理这种情况,要么不在启用确定性围栏支持的不同流中使用相同的信号量对象,要么在这些流之间添加显式依赖关系,以便按顺序对信号量进行信号通知。

如果信号量对象是以下任一类型:cudaExternalSemaphoreHandleTypeKeyedMutex, cudaExternalSemaphoreHandleTypeKeyedMutexKmt,那么键控互斥锁将使用cudaExternalSemaphoreSignalParams::params::keyedmutex::key中指定的键值进行释放。

Note:

另请参阅:

cudaImportExternalSemaphore, cudaDestroyExternalSemaphore, cudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaWaitExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreWaitParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
等待一组外部信号量对象。
参数
extSemArray
- External semaphores to be waited on
paramsArray
- Array of semaphore parameters
numExtSems
- Number of semaphores to wait on
stream
- Stream to enqueue the wait operations in
描述

在指定流中对一组外部分配的信号量对象执行等待操作入队。这些操作将在流中所有先前操作完成后执行。

等待信号量的确切语义取决于对象的类型。

如果信号量对象是以下任一类型:cudaExternalSemaphoreHandleTypeOpaqueFdcudaExternalSemaphoreHandleTypeOpaqueWin32cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt,那么等待该信号量将一直阻塞直到信号量进入已触发状态。随后信号量会被重置为未触发状态。因此每个信号操作只能对应一个等待操作。

如果信号量对象是以下任意一种类型:cudaExternalSemaphoreHandleTypeD3D12FencecudaExternalSemaphoreHandleTypeD3D11FencecudaExternalSemaphoreHandleTypeTimelineSemaphoreFdcudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32,那么等待该信号量将一直持续,直到信号量的值大于或等于cudaExternalSemaphoreWaitParams::params::fence::value。

如果信号量对象的类型是cudaExternalSemaphoreHandleTypeNvSciSync,那么等待该信号量将一直阻塞,直到与此信号量对象关联的NvSciSyncObj的信号发送方触发了cudaExternalSemaphoreSignalParams::params::nvSciSync::fence信号。默认情况下,等待此类外部信号量对象会针对所有以cudaExternalMemoryHandleTypeNvSciBuf方式导入的外部内存对象执行适当的内存同步操作,这确保了同一组NvSciBuf内存对象的其他导入者进行的后续访问具有一致性。可以通过指定标志cudaExternalSemaphoreWaitSkipNvSciBufMemSync来跳过这些操作,这在不需要数据一致性时可用作性能优化手段。但在需要数据一致性的场景下指定此标志将导致未定义行为。此外,对于类型为cudaExternalSemaphoreHandleTypeNvSciSync的信号量对象,如果用于创建NvSciSyncObj的NvSciSyncAttrList未在cudaDeviceGetNvSciSyncAttributes中将标志设置为cudaNvSciSyncAttrWait,则该API将返回cudaErrorNotSupported。

如果信号量对象是以下任一类型:cudaExternalSemaphoreHandleTypeKeyedMutex, cudaExternalSemaphoreHandleTypeKeyedMutexKmt,则当使用cudaExternalSemaphoreSignalParams::params::keyedmutex::key中指定的键释放时,或者直到cudaExternalSemaphoreSignalParams::params::keyedmutex::timeoutMs指定的超时时间过去时,将获取键控互斥锁。超时间隔可以是以毫秒为单位的有限值,也可以是无限值。如果指定了无限值,则超时永远不会过去。必须使用Windows INFINITE宏来指定无限超时。

Note:

另请参阅:

cudaImportExternalSemaphore, cudaDestroyExternalSemaphore, cudaSignalExternalSemaphoresAsync