是否可以直接从GPU (CUDA/openCL)访问硬盘/闪存盘,并直接从GPU的内存加载/存储内容?
我试图避免复制东西从磁盘到内存,然后复制到GPU的内存。
我读过关于Nvidia GPUDirect的文章,但不确定它是否像我前面解释的那样。它谈到了远程GPU内存和磁盘,但在我的例子中,磁盘是GPU的本地磁盘。
基本思想是加载内容(类似dma),->执行一些操作,->存储内容回到磁盘(同样是以dma的方式)。
我试图在这里尽可能少地涉及CPU和RAM。
请随时提供任何有关设计的建议。
发布于 2015-01-03 00:40:21
对于其他人来说,“懒散松绑”或多或少地做了我想做的事情。
通过下面的步骤,看看这是否对你有帮助。
使用RDMA对GPUDirect最直接的实现是在每次传输之前插入内存,并在传输完成后立即将其解锁。不幸的是,这在一般情况下表现很差,因为钉扎和未固定内存是昂贵的操作。然而,执行RDMA传输所需的其余步骤可以在不进入内核的情况下快速执行(可以使用MMIO寄存器/命令列表缓存和重放DMA列表)。 因此,延迟解紧内存是高性能RDMA实现的关键。它所暗示的是,即使在传输完成之后,也要将内存固定住。这利用了这样一个事实,即相同的内存区域很可能将用于未来的DMA传输,因此延迟解钉可以保存引脚/解锁操作。 延迟去钉扎的示例实现将保留一组固定内存区域,并且只有在区域的总大小达到某个阈值时(例如最近使用最少的内存区域),或者如果由于条空间耗尽而钉扎一个新区域失败(请参阅PCI条大小)。
这里有一个指向应用指南和nvidia博士的链接。
发布于 2016-04-27 19:49:55
为了使用这个特性,我在x64上写了一个小例子来实现这个功能。在本例中,内核“直接”访问磁盘空间。实际上,正如@RobertCrovella前面提到的,操作系统正在做这项工作,可能需要一些CPU工作,但没有补充编码。
__global__ void kernel(int4* ptr)
{
int4 val ; val.x = threadIdx.x ; val.y = blockDim.x ; val.z = blockIdx.x ; val.w = gridDim.x ;
ptr[threadIdx.x + blockDim.x * blockIdx.x] = val ;
ptr[160*1024*1024 + threadIdx.x + blockDim.x * blockIdx.x] = val ;
}
#include "Windows.h"
int main()
{
// 4GB - larger than installed GPU memory
size_t size = 256 * 1024 * 1024 * sizeof(int4) ;
HANDLE hFile = ::CreateFile ("GPU.dump", (GENERIC_READ | GENERIC_WRITE), 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;
HANDLE hFileMapping = ::CreateFileMapping (hFile, 0, PAGE_READWRITE, (size >> 32), (int)size, 0) ;
void* ptr = ::MapViewOfFile (hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, size) ;
::cudaSetDeviceFlags (cudaDeviceMapHost) ;
cudaError_t er = ::cudaHostRegister (ptr, size, cudaHostRegisterMapped) ;
if (cudaSuccess != er)
{
printf ("could not register\n") ;
return 1 ;
}
void* d_ptr ;
er = ::cudaHostGetDevicePointer (&d_ptr, ptr, 0) ;
if (cudaSuccess != er)
{
printf ("could not get device pointer\n") ;
return 1 ;
}
kernel<<<256,256>>> ((int4*)d_ptr) ;
if (cudaSuccess != ::cudaDeviceSynchronize())
{
printf ("error in kernel\n") ;
return 1 ;
}
if (cudaSuccess != ::cudaHostUnregister (ptr))
{
printf ("could not unregister\n") ;
return 1 ;
}
::UnmapViewOfFile (ptr) ;
::CloseHandle (hFileMapping) ;
::CloseHandle (hFile) ;
::cudaDeviceReset() ;
printf ("DONE\n");
return 0 ;
}发布于 2020-10-14 04:22:12
真正的解决方案就在眼前!
早期访问:https://developer.nvidia.com/gpudirect-storage
GPUDirect (GDS)是GPUDirect家族的最新成员。GDS为GPU内存和存储器之间的直接内存访问(DMA)传输提供了直接数据路径,从而避免了CPU间的弹跳缓冲区。这种直接路径增加了系统带宽,减少了CPU上的延迟和利用率负载。
https://stackoverflow.com/questions/27282273
复制相似问题