内存文件映射是直接将磁盘数据映射为虚拟地址空间中,并不是直接加载到主机内存中,
而cuda 的memcpy 需要从内存拷贝到显存,这样的话 cuda 的memcpy等就不起作用了?
测试了下 是可以的
楼主您好,这个是个绝妙的思路,这个思路直接将硬盘文件映射为设备可见的一段缓冲区,
但遗憾的是:
这个目前还不被支持。
理由如下:
(1)您将硬盘文件映射为一段内存,这个是可以的。
(2)您将内存就地锁定,然后获取设备指针。这个也是可以。
但(1)(2)结合起来是不可以的,因为此时在锁定的过程中,实际上将完成磁盘文件的全部读取,和您的直接分配文件大小的内存,然后读取文件全部内容,然后将内存映射到设备空间无区别了。
此时将无法实现随用随读,kernel访问到哪里,硬盘文件自动读取哪里并自动pci-e传输的特性的。
您的设想需要能映射pageable memory的GPU硬件的支持,此时:
方可直接将硬盘文件映射到显卡上,并实现随用随读随传输。
但可惜的是,目前GPU还不支持此特性。
建议的解决方案:
等待支持映射pageable memory的CUDA GPU出现(以及相应的cuda软件支持出现)。
我用了这样一段代码测试:
前面是内存映射基本操作。
while(qwFileSize > 0)
{
if (qwFileSize < dwGran)
dwBlockBytes = qwFileSize;
//映射视图
LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS,
(DWORD)qwFileOffSet >> 32, (DWORD)qwFileOffSet & 0xFFFFFFFF, dwBlockBytes);
if(lpbMapAddress == NULL)
{
printf("映射文件映射失败,错误代码:%d\r\n", GetLastError());
return 1;
}
///测试
BYTE* dst;
cudaError_t er = cudaMalloc( (void**)&dst, dwBlockBytes * sizeof(BYTE));
er = cudaMemcpy(dst, lpbMapAddress, dwBlockBytes * sizeof(BYTE),cudaMemcpyHostToDevice );
BYTE* hst;
hst = (BYTE*) malloc( dwBlockBytes * sizeof(BYTE));
kernel_test<<<1,1>>>( dst ,dwBlockBytes);
er = cudaMemcpy( hst,dst, dwBlockBytes*sizeof(BYTE),cudaMemcpyDeviceToHost);
//// 这里发现hst 中存储了正确的值
}
是不是说明 cuda 是支持内存文件映射的呢
您完全无视了我的2#回复。极度伤心中。
这个显然不是,这个只是普通的CPU上对文件映射的内存的访问而已。
您已知可以在cpu上使用文件映射的内存的,例如您直接的cpu上的int *p这种访问,
那么其他的host上的函数(例如cudaMemcpy, 当然,细节略微有区别)这么干自然也是在host上访问。
显然您host上cudaMemcpy能访问host上的映射内存,不是奇葩特性的。
显然不是您的GPU支持的CUDA特性。。。
您应当重新阅读我的2#.
版主不好意思,刚才是没大看懂您的话,您的意思是直接映射到设备上的方式,经过您的进一步解释 ,现在明白了。
非常感谢!
嗯嗯。
如果映射到内存上,然后在CPU上用,那么任何一个CPU/OS都是支持的。
以及,那样实际上变成和CUDA无关了,是吧。
感谢来访。