__host__​cudaError_t cudaMallocManaged ( void** devPtr, size_t size, unsigned int flags = cudaMemAttachGlobal ) 该函数分配由统一内存系统自动管理的内存。 参数 devPtr

  • 分配的设备内存的指针 size
  • 请求的分配大小(以字节为单位) flags
  • 必须是cudaMemAttachGlobal或cudaMemAttachHost之一(默认为cudaMemAttachGlobal) 返回值 cudaSuccess,cudaErrorMemoryAllocation,cudaErrorNotSupported,cudaErrorInvalidValue

描述 在设备上分配大小为size字节的受管内存,并在*devPtr中返回指向已分配内存的指针。如果设备不支持分配受管内存,则返回cudaErrorNotSupported。可以使用设备属性cudaDevAttrManagedMemory查询对受管内存的支持。分配的内存适合任何类型的变量。内存不会被清除。如果size为0,则cudaMallocManaged返回cudaErrorInvalidValue。该指针在CPU上和支持受管内存的系统中的所有GPU上都是有效的。对该指针的所有访问必须遵守统一内存编程模型。

flags指定此分配的默认流关联。flags必须是cudaMemAttachGlobal或cudaMemAttachHost之一。flags的默认值为cudaMemAttachGlobal。如果指定了cudaMemAttachGlobal,则可以从任何设备上的任何流访问该内存。如果指定了cudaMemAttachHost,则不应从具有设备属性cudaDevAttrConcurrentManagedAccess为零的设备访问分配;在这些设备上,需要显式调用cudaStreamAttachMemAsync才能启用访问。

如果稍后通过cudaStreamAttachMemAsync将关联更改为单个流,则销毁该流时,将恢复由cudaMallocManaged指定的默认关联。对于__managed__变量,默认关联始终为cudaMemAttachGlobal。请注意,销毁流是一个异步操作,因此,直到流中的所有工作完成,才会发生默认关联的更改。

使用cudaMallocManaged分配的内存应使用cudaFree释放。

对于具有设备属性cudaDevAttrConcurrentManagedAccess非零值的GPU,可以进行设备内存超额分配。这些GPU上的受管内存可能随时被统一内存驱动程序从设备内存驱逐到主机内存,以为其他分配腾出空间。

在所有GPU具有设备属性cudaDevAttrConcurrentManagedAccess非零值的多GPU系统中,当此API返回时,可能不会填充受管内存,而是在访问时填充。在这种系统中,受管内存可以随时迁移到任何处理器的内存。统一内存驱动程序将使用启发式方法尽可能地维护数据局部性并防止过多的页面错误。应用程序还可以通过cudaMemAdvise指导驱动程序有关内存使用模式。应用程序还可以通过cudaMemPrefetchAsync将内存显式迁移到所需处理器的内存中。

在所有GPU都具有设备属性cudaDevAttrConcurrentManagedAccess为零,并且所有GPU都相互支持对等体的多GPU系统中,对于cudaMallocManaged调用时处于活动状态的GPU上创建受管内存的物理存储。所有其他GPU将通过PCIe总线上的对等映射引用数据以降低带宽。统一内存驱动程序不会在此类GPU之间迁移内存。

在不是所有GPU都相互支持对等体,并且至少有一个GPU的设备属性cudaDevAttrConcurrentManagedAccess为零的多GPU系统中,所选的物理存储受管内存的位置取决于系统。

在Linux上,只要当前一组活动上下文位于彼此具有对等体支持或具有设备属性cudaDevAttrConcurrentManagedAccess非零值的设备上,所选位置将为设备内存。如果有一个活动上下文位于没有该设备属性非零值的GPU上,并且它没有与其他设备具有活动上下文的设备相互支持,则物理存储的位置将为“零拷贝”或主机内存。请注意,这意味着如果在不具有该设备属性非零值且不支持与至少一个具有活动上下文的其他设备相互支持的GPU上创建新上下文,则位于设备内存中的受管内存将迁移到主机内存。这反过来意味着如果没有足够的主机内存来迁移所有受管分配,则上下文创建可能会失败。

在Windows上,物理存储始终在“零拷贝”或主机内存中创建。所有GPU将通过PCIe总线上的对等映射引用数据以降低带宽。在这种情况下,建议使用环境变量CUDA_VISIBLE_DEVICES来限制CUDA仅使用具有对等体支持的GPU。或者,用户也可以将CUDA_MANAGED_FORCE_DEVICE_ALLOC设置为非零值,以强制驱动程序始终使用设备内存作为物理存储。当将此环境变量设置为非零值时,该进程中使用的所有支持受管内存的设备都必须相互支持对等体。如果使用支持受管内存的设备并且它与之前在该进程中使用的任何其他支持受管内存的设备都不兼容,则会返回错误cudaErrorInvalidDevice,即使在这些设备上调用了cudaDeviceReset。这些环境变量在CUDA编程指南的“CUDA环境变量”一节中有描述。

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

请注意,如果此调用尝试初始化内部CUDA RT状态,则此功能也可能返回cudaErrorInitializationError,cudaErrorInsufficientDriver或cudaErrorNoDevice。

请注意,如cudaStreamAddCallback所指定,回调函数中不得调用任何CUDA函数。在这种情况下,可能会返回诊断性的cudaErrorNotPermitted。

另请参阅:

cudaMallocPitch,cudaFree,cudaMallocArray,cudaFreeArray,cudaMalloc3D,cudaMalloc3DArray,cudaMallocHost(C API),cudaFreeHost,cudaHostAlloc,cudaDeviceGetAttribute,cudaStreamAttachMemAsync,cuMemAllocManage


原文地址: https://www.cveoy.top/t/topic/ePaJ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录