Io 高效地将大文件(高达2GB)传输到CUDA GPU?
我正在开发一个GPU加速程序,它需要读取整个大小可变的文件。我的问题是,从文件读取并传输到协处理器(CUDA设备)的最佳字节数是多少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
这些文件可能大到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
,将chunkk-1
传输回主机,并将chunkk+1
从主机传输到设备。双向重叠需要特斯拉GPU,但即使在GeForce上也可以重叠一个方向。此外,还可以使用cuGetMemInfo
获取可用内存量@Mick:自从Cuda3.1以来,运行时API中就已经有了cudaGetMemInfo,它做了同样的事情,但不必在宿主代码中混合使用运行时和驱动程序API。