6.7. 外部资源互操作性

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

函数

__host__cudaError_t cudaDestroyExternalMemory ( cudaExternalMemory_t extMem )
销毁外部内存对象。
__host__cudaError_t cudaDestroyExternalSemaphore ( cudaExternalSemaphore_t extSem )
销毁外部信号量。
__host__cudaError_t cudaExternalMemoryGetMappedBuffer ( void** devPtr, cudaExternalMemory_t extMem, const cudaExternalMemoryBufferDesc* bufferDesc )
将缓冲区映射到导入的内存对象上。
__host__cudaError_t cudaExternalMemoryGetMappedMipmappedArray ( cudaMipmappedArray_t* mipmap, cudaExternalMemory_t extMem, const cudaExternalMemoryMipmappedArrayDesc* mipmapDesc )
将 CUDA mipmapped 数组映射到外部内存对象上。
__host__cudaError_t cudaImportExternalMemory ( cudaExternalMemory_t* extMem_out, const cudaExternalMemoryHandleDesc* memHandleDesc )
导入外部内存对象。
__host__cudaError_t cudaImportExternalSemaphore ( cudaExternalSemaphore_t* extSem_out, const cudaExternalSemaphoreHandleDesc* semHandleDesc )
导入外部信号量。
__host__cudaError_t cudaSignalExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreSignalParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
发信号通知一组外部信号量对象。
__host__cudaError_t cudaWaitExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreWaitParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
等待一组外部信号量对象。

函数

__host__cudaError_t cudaDestroyExternalMemory ( cudaExternalMemory_t extMem )
销毁外部内存对象。
参数
extMem
- 要销毁的外部内存对象
描述

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

注意

另请参阅

cudaImportExternalMemory, cudaExternalMemoryGetMappedBuffer, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaDestroyExternalSemaphore ( cudaExternalSemaphore_t extSem )
销毁外部信号量。
参数
extSem
- 要销毁的外部信号量
描述

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

注意

另请参阅

cudaImportExternalSemaphore, cudaSignalExternalSemaphoresAsync, cudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaExternalMemoryGetMappedBuffer ( void** devPtr, cudaExternalMemory_t extMem, const cudaExternalMemoryBufferDesc* bufferDesc )
将缓冲区映射到导入的内存对象上。
参数
devPtr
- 返回的缓冲区设备指针
extMem
- 外部内存对象的句柄
bufferDesc
- 缓冲区描述符
描述

将缓冲区映射到导入的内存对象上,并在以下位置返回设备指针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 释放。

注意

另请参阅

cudaImportExternalMemory, cudaDestroyExternalMemory, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaExternalMemoryGetMappedMipmappedArray ( cudaMipmappedArray_t* mipmap, cudaExternalMemory_t extMem, const cudaExternalMemoryMipmappedArrayDesc* mipmapDesc )
将 CUDA mipmapped 数组映射到外部内存对象上。
参数
mipmap
- 返回的 CUDA mipmapped 数组
extMem
- 外部内存对象的句柄
mipmapDesc
- CUDA 数组描述符
描述

将 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 释放。

注意

另请参阅

cudaImportExternalMemory, cudaDestroyExternalMemory, cudaExternalMemoryGetMappedBuffer

注意

如果 cudaExternalMemoryHandleDesc::type 是 cudaExternalMemoryHandleTypeNvSciBuf,则 cudaExternalMemoryMipmappedArrayDesc::numLevels 不得大于 1。

__host__cudaError_t cudaImportExternalMemory ( cudaExternalMemory_t* extMem_out, const cudaExternalMemoryHandleDesc* memHandleDesc )
导入外部内存对象。
参数
extMem_out
- 返回的外部内存对象句柄
memHandleDesc
- 内存导入句柄描述符
描述

导入外部分配的内存对象,并在以下位置返回其句柄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::type 是 cudaExternalMemoryHandleTypeOpaqueFd,则 cudaExternalMemoryHandleDesc::handle::fd 必须是引用内存对象的有效文件描述符。当句柄成功导入时,文件描述符的所有权将转移给 CUDA 驱动程序。导入后对文件描述符执行任何操作都会导致未定义的行为。

如果 cudaExternalMemoryHandleDesc::type 是 cudaExternalMemoryHandleTypeOpaqueWin32,则 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::type 是 cudaExternalMemoryHandleTypeOpaqueWin32Kmt,则 cudaExternalMemoryHandleDesc::handle::win32::handle 必须为非 NULL,而 cudaExternalMemoryHandleDesc::handle::win32::name 必须为 NULL。指定的句柄必须是全局共享的 KMT 句柄。此句柄不持有对底层对象的引用,因此当对内存对象的所有引用都被销毁时,它将无效。

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

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

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

如果 cudaExternalMemoryHandleDesc::type 是 cudaExternalMemoryHandleTypeD3D11ResourceKmt,则 cudaExternalMemoryHandleDesc::handle::win32::handle 必须为非 NULL,而 cudaExternalMemoryHandleDesc::handle::win32::name 必须为 NULL。指定的句柄必须是由 IDXGIResource::GetSharedHandle 在引用 ID3D11Resource 对象时返回的有效共享 KMT 句柄。

如果 cudaExternalMemoryHandleDesc::type 是 cudaExternalMemoryHandleTypeNvSciBuf,则 cudaExternalMemoryHandleDesc::handle::nvSciBufObject 必须为 NON-NULL 并且引用有效的 NvSciBuf 对象。如果导入到 CUDA 中的 NvSciBuf 对象也由其他驱动程序映射,则应用程序必须使用 cudaWaitExternalSemaphoresAsync 或 cudaSignalExternalSemaphoresAsync 作为适当的屏障,以保持 CUDA 与其他驱动程序之间的一致性。有关内存同步,请参阅 cudaExternalSemaphoreWaitSkipNvSciBufMemSync 和 cudaExternalSemaphoreSignalSkipNvSciBufMemSync。

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

在 cudaExternalMemoryHandleDesc::flags 中指定标志 cudaExternalMemoryDedicated 表示该资源是专用资源。专用资源的定义超出了此扩展的范围。如果 cudaExternalMemoryHandleDesc::type 是以下类型之一,则必须设置此标志:cudaExternalMemoryHandleTypeD3D12Resource、cudaExternalMemoryHandleTypeD3D11Resource、cudaExternalMemoryHandleTypeD3D11ResourceKmt

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

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

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

  • 如果导入到 CUDA 中的 Vulkan 内存映射到 CPU 上,则应用程序必须使用 vkInvalidateMappedMemoryRanges/vkFlushMappedMemoryRanges 以及适当的 Vulkan 管道屏障,以保持 CPU 和 GPU 之间的一致性。有关这些 API 的更多信息,请参阅 Vulkan 规范中的“Synchronization and Cache Control”章节。

另请参阅

cudaDestroyExternalMemory, cudaExternalMemoryGetMappedBuffer, cudaExternalMemoryGetMappedMipmappedArray

__host__cudaError_t cudaImportExternalSemaphore ( cudaExternalSemaphore_t* extSem_out, const cudaExternalSemaphoreHandleDesc* semHandleDesc )
导入外部信号量。
参数
extSem_out
- 返回的外部信号量句柄
semHandleDesc
- 信号量导入句柄描述符
描述

导入外部分配的同步对象,并在以下位置返回其句柄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,则它必须表示由 ID3D12Device::CreateSharedHandle 返回的有效共享 NT 句柄(当引用 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,则它表示由 IDXGIResource1::CreateSharedHandle 返回的有效共享 NT 句柄(当引用 IDXGIKeyedMutex 对象时)。

如果 cudaExternalSemaphoreHandleDesc::typecudaExternalSemaphoreHandleTypeKeyedMutexKmt,则 cudaExternalSemaphoreHandleDesc::handle::win32::handle 必须为非 NULL,而 cudaExternalSemaphoreHandleDesc::handle::win32::name 必须为 NULL。指定的句柄必须表示由 IDXGIResource::GetSharedHandle 返回的有效 KMT 句柄(当引用 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,则它必须命名一个有效的同步对象。

注意

另请参阅

cudaDestroyExternalSemaphorecudaSignalExternalSemaphoresAsynccudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaSignalExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreSignalParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
发出对一组外部信号量对象的信号。
参数
extSemArray
- 要发出信号的外部信号量集
paramsArray
- 信号量参数数组
numExtSems
- 要发出信号的信号量数量
stream
- 将信号操作排队的流
描述

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

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

如果信号量对象是以下任何类型: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'。 用户应跟踪在信号量对象上排队的信号计数,并相应地插入等待。 当从多个流发出此类信号量对象的信号时,由于并发流执行,信号量被发出信号的顺序可能是非确定性的。 这可能会导致信号量的等待者被错误地解除阻塞。 用户应处理此类情况,方法是不在不同的流中使用启用确定性栅栏支持的同一信号量对象,或者在这些流之间添加显式依赖关系,以便按顺序发出信号量。

如果信号量对象是以下任何类型:cudaExternalSemaphoreHandleTypeKeyedMutexcudaExternalSemaphoreHandleTypeKeyedMutexKmt,则将使用 cudaExternalSemaphoreSignalParams::params::keyedmutex::key 中指定的键释放键控互斥锁。

注意

另请参阅

cudaImportExternalSemaphorecudaDestroyExternalSemaphorecudaWaitExternalSemaphoresAsync

__host__cudaError_t cudaWaitExternalSemaphoresAsync ( const cudaExternalSemaphore_t* extSemArray, const cudaExternalSemaphoreWaitParams* paramsArray, unsigned int  numExtSems, cudaStream_t stream = 0 )
等待一组外部信号量对象。
参数
extSemArray
- 要等待的外部信号量
paramsArray
- 信号量参数数组
numExtSems
- 要等待的信号量数量
stream
- 将等待操作排队的流
描述

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

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

如果信号量对象是以下任何类型:cudaExternalSemaphoreHandleTypeOpaqueFdcudaExternalSemaphoreHandleTypeOpaqueWin32cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt,则等待信号量将等待直到信号量达到已发出信号状态。然后,信号量将被重置为未发出信号状态。因此,对于每个信号操作,只能有一个等待操作。

如果信号量对象是以下任何类型:cudaExternalSemaphoreHandleTypeD3D12FencecudaExternalSemaphoreHandleTypeD3D11FencecudaExternalSemaphoreHandleTypeTimelineSemaphoreFdcudaExternalSemaphoreHandleTypeTimelineSemaphoreWin32,则等待信号量将等待直到信号量的值大于或等于 cudaExternalSemaphoreWaitParams::params::fence::value。

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

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

注意

另请参阅

cudaImportExternalSemaphorecudaDestroyExternalSemaphorecudaSignalExternalSemaphoresAsync