当将pageable host Memory数据送到device时,CUDA驱动会首先分配一个临时的page-locked或者pinned host Memory,并将host的数据放到这个临时空间里。然后GPU从这个所谓的pinned Memory中获取数据,如下图所示:
image.png
因此显式地直接分配锁页内存时,内存拷贝的速度会更快。
Zero-copy的实质就是pinned memory并且被映射到了device的地址空间。
函数1
//分配
__host__cudaError_t cudaMallocHost ( void** ptr, size_t size )
//释放
__host__cudaError_t cudaFreeHost ( void* ptr )
注意:此函数 device端无法获得指针。
函数2
//分配
__host__cudaError_t cudaHostAlloc ( void** pHost, size_t size, unsigned int flags )
//释放
__host__cudaError_t cudaFreeHost ( void* ptr )
关于flag:
当使用cudaHostAllocDefault (0) 时,cudaHostAlloc和cudaMallocHost等价。
当使用cudaHostAllocPortable时,分配的pinned memory对所有CUDA context都有效,而不是单单执行分配此操作的那个context或者说线程。
cudaHostAllocWriteCombined是在特殊系统配置情况下使用的,这块pinned memory在PCIE上的传输更快,但是对于host自己来说,却没什么效率。所以该选项一般用来让host去写,然后device读。
最常用的是cudaHostAllocMapped,就是返回一个标准的zero-copy。可以用下面的API来获取device端的地址:
cudaError_t cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags);//注意:flags目前设置为0
前面还要有cudaSetDeviceFlags(cudaDeviceMapHost)
(使用runtime api时是隐式的,使用driver api时要自己设定)
其他flag:
cudaHostAllocWriteCombined:以写合并(WC)的方式分配内存。在某些系统配置上,WC内存可以更快速地跨PCI Express总线传输,但大多数cpu无法有效读取。对于缓冲区来说,WC内存是一个很好的选择,CPU将写入缓冲区,设备将通过映射的固定内存或host->设备传输读取缓冲区
网友评论