Io 高效地将大文件(高达2GB)传输到CUDA GPU?

Io 高效地将大文件(高达2GB)传输到CUDA GPU?,io,cuda,file-transfer,large-files,bandwidth,Io,Cuda,File Transfer,Large Files,Bandwidth,我正在开发一个GPU加速程序,它需要读取整个大小可变的文件。我的问题是,从文件读取并传输到协处理器(CUDA设备)的最佳字节数是多少 这些文件可能大到2GiB,因此创建该大小的缓冲区似乎不是最好的主意。您可以在设备上使用最大大小的缓冲区。在此之后,将此大小的输入数据块从主机复制到设备,进行处理,复制回结果并继续 // Your input data on host int hostBufNum = 5600000; int* hostBuf = ...; // Assume this is

我正在开发一个GPU加速程序,它需要读取整个大小可变的文件。我的问题是,从文件读取并传输到协处理器(CUDA设备)的最佳字节数是多少


这些文件可能大到2GiB,因此创建该大小的缓冲区似乎不是最好的主意。

您可以在设备上使用最大大小的缓冲区。在此之后,将此大小的输入数据块从主机复制到设备,进行处理,复制回结果并继续

// Your input data on host
int hostBufNum = 5600000;
int* hostBuf   = ...;

// Assume this is largest device buffer you can allocate
int devBufNum = 1000000;
int* devBuf;

cudaMalloc( &devBuf, sizeof( int ) * devBufNum );

int* hostChunk  = hostBuf;
int hostLeft    = hostBufNum;
int chunkNum    = ( hostLeft < devBufNum ) ? hostLeft : devBufNum;

do
{
    cudaMemcpy( devBuf, hostChunk, chunkNum * sizeof( int ) , cudaMemcpyHostToDevice);
    doSomethingKernel<<< >>>( devBuf, chunkNum );

    hostChunk   = hostChunk + chunkNum;
    hostLeft    = hostBufNum - ( hostChunk - hostBuf );
} while( hostLeft > 0 );    
//主机上的输入数据
int hostBufNum=5600000;
int*hostBuf=。。。;
//假设这是您可以分配的最大设备缓冲区
int devBufNum=1000000;
int*devBuf;
cudaMalloc(&devBuf,sizeof(int)*devBufNum);
int*hostChunk=hostBuf;
int hostLeft=hostBufNum;
int chunkNum=(hostLeft(devBuf,chunkNum);
hostChunk=hostChunk+chunkNum;
hostLeft=hostBufNum-(hostChunk-hostBuf);
}而(左>0);

如果您可以将函数拆分,以便处理卡上的块,那么您应该考虑使用流(cudaStream\t)

如果在多个流中安排加载和内核执行,则可以让一个流加载数据,而另一个流在卡上执行内核,从而在执行内核时隐藏一些数据传输时间


您需要声明一个缓冲区,该缓冲区的块大小是您声明的流的多少倍(据我所知,对于compute capability 1.x,最多16个)。

我已经计划好了,但是,输入数据的大小应该是多少?你可以在设备上分配的最大数组的大小。你可以考虑使用比内存中更小的块的异步内存拷贝(最多一半)。以及并行处理chunk
k
,将chunk
k-1
传输回主机,并将chunk
k+1
从主机传输到设备。双向重叠需要特斯拉GPU,但即使在GeForce上也可以重叠一个方向。此外,还可以使用
cuGetMemInfo
获取可用内存量@Mick:自从Cuda3.1以来,运行时API中就已经有了cudaGetMemInfo,它做了同样的事情,但不必在宿主代码中混合使用运行时和驱动程序API。