我注意到将数据传输到最近的高端GPU比将其收集回CPU更快。以下是使用由旧版Nvidia K20运行的mathworks技术支持和最近使用PCIE的Nvidia P100提供给我的基准测试功能的结果:
Using a Tesla P100-PCIE-12GB GPU.
Achieved peak send speed of 11.042 GB/s
Achieved peak gather speed of 4.20609 GB/s
Using a Tesla K20m GPU.
Achieved peak send speed of 2.5269 GB/s
Achieved peak gather speed of 2.52399 GB/s
我已在下面附上基准功能以供参考。 P100不对称的原因是什么?这个系统是依赖还是近期高端GPU的标准?可以提高聚集速度吗?
gpu = gpuDevice();
fprintf('Using a %s GPU.\n', gpu.Name)
sizeOfDouble = 8; % Each double-precision number needs 8 bytes of storage
sizes = power(2, 14:28);
sendTimes = inf(size(sizes));
gatherTimes = inf(size(sizes));
for ii=1:numel(sizes)
numElements = sizes(ii)/sizeOfDouble;
hostData = randi([0 9], numElements, 1);
gpuData = randi([0 9], numElements, 1, 'gpuArray');
% Time sending to GPU
sendFcn = @() gpuArray(hostData);
sendTimes(ii) = gputimeit(sendFcn);
% Time gathering back from GPU
gatherFcn = @() gather(gpuData);
gatherTimes(ii) = gputimeit(gatherFcn);
end
sendBandwidth = (sizes./sendTimes)/1e9;
[maxSendBandwidth,maxSendIdx] = max(sendBandwidth);
fprintf('Achieved peak send speed of %g GB/s\n',maxSendBandwidth)
gatherBandwidth = (sizes./gatherTimes)/1e9;
[maxGatherBandwidth,maxGatherIdx] = max(gatherBandwidth);
fprintf('Achieved peak gather speed of %g GB/s\n',max(gatherBandwidth))
编辑:我们现在知道它不依赖于系统(请参阅注释)。我仍然想知道不对称的原因或是否可以改变。
答案 0 :(得分:2)
系统:Win10,32GB DDR4-2400Mhz RAM,i7 6700K。 MATLAB:R2018a。
Using a GeForce GTX 660 GPU.
Achieved peak send speed of 7.04747 GB/s
Achieved peak gather speed of 3.11048 GB/s
Warning: The measured time for F may be inaccurate because it is running too fast. Try measuring something that takes
longer.
投稿人:Dev-iL
系统:Win7,32GB RAM,i7 4790K。 MATLAB:R2018a。
Using a Quadro P6000 GPU.
Achieved peak send speed of 1.43346 GB/s
Achieved peak gather speed of 1.32355 GB/s
投稿人:Dev-iL
答案 1 :(得分:1)
我不熟悉Matlab GPU工具箱,但是我怀疑第二次传输(从GPU取回数据)是在第一次传输结束之前开始的。
% Time sending to GPU
sendFcn = @() gpuArray(hostData);
sendTimes(ii) = gputimeit(sendFcn);
%
%No synchronization here
%
% Time gathering back from GPU
gatherFcn = @() gather(gpuData);
gatherTimes(ii) = gputimeit(gatherFcn);
关于C程序的类似问题发布在这里:
copy from GPU to CPU is slower than copying CPU to GPU
在这种情况下,在GPU上启动线程并从GPU取回结果数据后,没有显式同步。 因此,在c cudaMemcpy()中,获取数据的函数必须等待GPU结束之前启动的线程,然后再传输数据,从而增加了数据传输的时间。
使用Cuda C API,可以通过以下方法强制CPU等待GPU终止先前启动的线程:
cudaDeviceSynchronize();
然后才开始测量传输数据的时间。
也许在Matlab中也有一些同步原语。
在相同的答案中,建议使用(Cuda)事件测量时间。
在此有关优化数据传输的POST中,也很抱歉,事件用于测量数据传输时间:
https://devblogs.nvidia.com/how-optimize-data-transfers-cuda-cc/
两个方向上的数据传输时间相同。