是否可以直接从GPU(CUDA / openCL)访问硬盘/闪存盘并直接从GPU的内存加载/存储内容?
我试图避免将内容从磁盘复制到内存,然后将其复制到GPU的内存中。
我读过Nvidia GPUDirect,但不确定它是否符合我上面的解释。它讨论了远程GPU内存和磁盘,但我的情况下磁盘是GPU的本地磁盘。
基本思想是加载内容(类似于dma) - >做一些操作 - >将内容存储回磁盘(再次以dma方式)。
我试图尽可能少地涉及CPU和RAM。
请随时提供有关设计的任何建议。
答案 0 :(得分:12)
对于其他任何寻找此事的人来说,“懒惰的解决方案”'或多或少地做了我想要的事情。
通过以下内容查看这是否对您有所帮助。
使用RDMA进行GPUDirect的最简单的实现方法是 在每次传输之前固定内存,并在传输后立即取消固定 完成了。不幸的是,这一般表现不佳,如 固定和取消固定内存是昂贵的操作。剩下的 但是,可以执行执行RDMA传输所需的步骤 快速无需进入内核(DMA列表可以缓存和 使用MMIO寄存器/命令列表重播。
因此,延迟取消内存是高性能RDMA的关键 实现。这意味着,保持内存固定均匀 转移完成后。这利用了这个事实 很可能相同的内存区域将用于将来的DMA 转移因此懒惰取消固定销存/取消固定操作。
延迟取消固定的示例实现将保留一组固定 内存区域,只取消其中一些(例如至少 最近使用的一个)如果区域的总大小达到一些 阈值,或者由于BAR空间而导致新区域固定失败 耗尽(参见PCI BAR尺寸)。
以下是指向application guide和nvidia docs的链接。
答案 1 :(得分:4)
尝试使用此功能,我在Windows 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 ;
}
答案 2 :(得分:0)
真正的解决方案迫在眉睫!
早期访问:https://developer.nvidia.com/gpudirect-storage
GPUDirect®存储(GDS)是GPUDirect系列的最新产品。 GDS支持在GPU内存和存储之间进行直接内存访问(DMA)传输的直接数据路径,从而避免了通过CPU的反弹缓冲区。这种直接路径增加了系统带宽,并减少了CPU的等待时间和利用率负载。