系列文章目录
前言
这里跟大家分享内存管理第三篇:零拷贝内存。
一、零拷贝内存相关知识点
之前学习的CUDA知识中,主机不能直接访问设备变量,需要通过 c u d a M e m c p y cudaMemcpy cudaMemcpy函数实现主机与设备间数据拷贝,当然设备也不能直接访问主机变量。
这里介绍的零拷贝内存则是个例外,主机和设备都可以访问零拷贝内存。
注意,零拷贝内存相当于从全局内存中分出的一块独立内存,使用了固定内存技术实现零内存拷贝。
在CUDA核函数中使用零拷贝内存的优势如下:
(1)当设备内存不足时可利用主机内存
(2)避免主机和设备间的显示数据传输
(3)提高PCIe传输率
因为设备和主机都可以访问零拷贝内存数据,那么就要注意同步问题,避免主机和设备同时更改零拷贝内存中的数据,否则将产生脏数据。
零拷贝内存的技术实现主要靠固定内存(不可分页),该内存映射到设备地址空间中。可通过如下函数创建一个到固定内存的映射:
c u d a E r r o r _ t c u d a H o s t A l l o c ( v o i d ∗ ∗ p H o s t , s i z e _ t c o u n t , u n s i g n e d i n t f l a g s ) ; cudaError\_t\ cudaHostAlloc(void\ **pHost,\ size\_t\ count,\ unsigned\ int\ flags); cudaError_t cudaHostAlloc(void ∗∗pHost, size_t count, unsigned int flags);
零拷贝内存需要用 c u d a F r e e H o s t cudaFreeHost cudaFreeHost函数释放。
分配零拷贝内存的flags列举如下:
(1)cudaHostAllocDefault
cudaHostAlloc函数行为与分配固定内存函数cudaMallocHost函数一致;
(2)cudaHostAllocPortable
使函数返回能被所有CUDA上下文使用的固定内存,而不仅是执行内存分配的那一个。
(3)cudaHostAllocWriteCombined
使函数返回写结合内存,该内存可在某些系统配置(哪些系统配置呢?)通过PCIe总线上更快地传输,但是它在大多数主机上不能被有效地读取。
(4)cudaHostAllocMapped
这是零拷贝内存的最明显标志,可以实现主机写入和设备读取被映射到设备地址空间中的主机内存。
可通过下列函数获取映射到固定内存的设备指针:
c u d a E r r o r _ t c u d a H o s t G e t D e v i c e P o i n t e r ( v o i d ∗ ∗ p D e v i c e , v o i d ∗ p H o s t , u n s i g n e d i n t f l a g s ) ; cudaError\_t cudaHostGetDevicePointer(void\ **pDevice,\ void\ *pHost,\ unsigned\ int\ flags); cudaError