为什么在Matlab中对gpuArray进行repmat和reshape这么慢?

时间:2017-02-01 20:09:57

标签: matlab gpu

我目前的任务是使用gpu同时训练多个网络。我现在不能这样做,所以现在我尝试用数组做一些操作。

a = rand(1000, 1000, 'gpuArray');
tic; for i = 1 : 100 a .* a; end; toc;                 % line 1
tic; for i = 1 : 100 repmat(a, 3, 10); end; toc;       % line 2
tic; for i = 1 : 100 reshape(a, 10, 10000); end; toc;  % line 3

b = rand(1000, 1000);
tic; for i = 1 : 100 b .* b; end; toc;                 % line 4
tic; for i = 1 : 100 repmat(b, 3, 10); end; toc;       % line 5
tic; for i = 1 : 100 reshape(b, 10, 10000); end; toc;  % line 6

所以line 1 falser比line 4但是 line 2慢于line 5和 比line 3line 6 对于许多其他具有其他大小的阵列,可以看到比repmatreshape的GPU更快的CPU。 有人可以解释我应该做些什么来获得预期的加速度?

1 个答案:

答案 0 :(得分:1)

如果你看到任何令人惊讶的事情,你所看到的只是异步执行。 a .* a退出而没有实际执行任何操作,它只是设置GPU上的计算。所以你所有的时间都是将100个内核排队执行需要多长时间。您需要使用gputimeitwait(gpuDevice)来获取代码中的正确时间。也许在repmat执行时已达到队列限制,因此MATLAB被迫等待一些乘法发生,但我无法确定。

a = rand(1000, 1000, 'gpuArray');
b = gather(a);

fprintf('Times for @times: ');
fprintf('GPU: %f secs  ', gputimeit(@()a.*a));
fprintf('CPU: %f secs\n', timeit(@()b.*b));

fprintf('Times for @repmat: ');
fprintf('GPU: %f secs  ', gputimeit(@()repmat(a,3,10)));
fprintf('CPU: %f secs\n', timeit(@()repmat(b,3,10)));

fprintf('Times for @reshape: ');
fprintf('GPU: %f secs  ', gputimeit(@()reshape(a,10,100000)));
fprintf('CPU: %f secs\n', timeit(@()reshape(b,10,100000)));

输出:

Times for @times: GPU: 0.000382 secs  CPU: 0.001642 secs
Times for @repmat: GPU: 0.005186 secs  CPU: 0.032809 secs
Times for @reshape: GPU: 0.000053 secs  CPU: 0.000002 secs

reshape在CPU上可能真的更快(虽然噪音很小),因为在对象上调用方法所需的时间比直接检查或修改数组的属性要长。但实际上,它对于任何真正的GPU应用来说都是不重要的。

如果您的设备上没有类似的数字,那么毫无疑问这与GPU的质量有关。 repmat是一个高内存带宽功能 - 也许你有一个游戏卡或笔记本电脑芯片,其性能非常差的双精度阵列?您可以在single中尝试,看看情况是否有所改善。