使用 gpuArray 加速 Matlab 中的仿真



我有一个更新数组的 Matlab 模拟:

Array=zeros(1,1000) 

如下:

for j=1:100000 
Array=Array+rand(1,1000) 
end 

我的问题如下: 此循环是线性的,因此不能针对阵列中的每个插槽进行并列化,但不同的插槽是独立更新的。因此,Matlab 自然会使用 CPU 的所有内核在 parralell 中执行这样的数组操作。

我希望在我的 NVIDIA GPU 上执行相同的计算,以加快速度(利用那里的更多内核)。

问题是:天真地做

tic 
Array=gpuArray(zeros(1,1000));
for j=1:100000 
Array=Array+gpuArray(rand(1,1000));  
end  
toc 

结果计算时间延长了8倍!

一个。我做错了什么?

更新: b.也许有人可以提供另一个简单的例子,GPU 计算对它有益?我的目的是了解如何在 Matlab 中利用它来进行非常"繁重"的随机模拟(对大数组和矩阵的多个线性运算)。

什么都没有。

这就是 GPU 计算的工作方式。不幸的是,这不是魔法。CPU-GPU 通信很慢,非常慢。每次迭代,您都会在CPU上创建一个数组并将其发送到GPU,这是缓慢的部分。我敢肯定,CPU"+"操作中快得离谱的速度在 GPU 中甚至更快,但将信息发送到 GPU 所需的时间完全掩盖了这种改进。

您的代码几乎没有改进的余地。

它可能无助于整体速度(正如@Ander在他的回答中提到的),但你可以做的一个小改进是直接在GPU上构建随机数,如下所示:

rand(1, 10000, 'gpuArray')

通常,GPU 上的随机数生成比 CPU 上的要快得多。

您可以使用gpuArray版本的arrayfun更进一步,它将主体 JIT 编译为本机 GPU 代码。在我的GPU(Tesla K20c)上,这使得GPU版本比CPU版本快10倍。以下是完整脚本:

%% CPU version
tic
Array=zeros(1,1000);
for j=1:100000
Array=Array+rand(1,1000);
end
cpuTime = toc
%% GPU version
dev = gpuDevice();
tic
Array = zeros(1, 1000, 'gpuArray');
Array = arrayfun(@iFcn, Array);
wait(dev);
gpuTime = toc
%% Arrayfun body
function x = iFcn(x)
for j = 1:100000
x = x + rand;
end
end

最新更新