【问题标题】:Matlab is slow when using user defined function with calculation in GPU在 GPU 中使用用户定义的函数进行计算时,Matlab 很慢
【发布时间】:2014-10-17 14:01:07
【问题描述】:

当我运行下面显示的代码时,函数内的 tic/toc 对显示遍历所有行需要很短的时间(

tic

rnn.v = 11;
rnn.h = 101;
rnn.o = 7;
rnn.h_init = randn(1,rnn.h,'gpuArray');
rnn.W_vh = randn(rnn.v,rnn.h,'gpuArray');
rnn.W_hh = randn(rnn.h,rnn.h,'gpuArray');
rnn.W_ho = randn(rnn.h,rnn.o,'gpuArray');

inData.V = randn(10000,11,100,'gpuArray');
inData.TimeSteps =100;
inData.BatchSize = 10000;

[H,OX] = forward_pass(rnn, inData)
toc

rnn和inData中的所有矩阵都是gpuArray,所以所有的计算都是在GPU中进行的。输出也是 gpuArray。

function [H,OX] = forward_pass(rnn, inData)
        tic;
        %initial hidden state values
        H_init = gpuArray(repmat(rnn.h_init,[inData.BatchSize,1]));

        %initialize state H
        H = zeros(inData.BatchSize, rnn.h, inData.TimeSteps,'gpuArray');

        %initialize OX (which is H * Who)
        OX = zeros(inData.BatchSize, rnn.o, inData.TimeSteps,'gpuArray');

        for t = 1 : inData.TimeSteps

            if t == 1
                HX_t = H_init * rnn.W_hh... 
                        + inData.V(:,:,t) * rnn.W_vh;
            else
                HX_t = H(:,:,(t-1)) * rnn.W_hh... 
                        + inData.V(:,:,t) * rnn.W_vh;
            end

            H(:,:,t) = tanh(HX_t);
            OX(:,:,t) = H(:,:,t) * rnn.W_ho;


        end

        toc;
    end

通常,如果您使用gather() 函数,它会很慢。我没有使用gather() 函数将输出传输到工作区,我不知道为什么它仍然这么慢。看起来最后一行“结束”需要超过 2 秒。

有人知道如何加速函数调用吗?

【问题讨论】:

  • inData.V 是一个 10000x11x100 gpuArray。 rnn.W_vh 是 11x101 gpuArray,rnn.W_ho 是 101x7 gpuArray,H 是 10000x101x100 gpuArray,OX 是 10000x7x100 gpuArray。
  • rnn.v = 11; rnn.h = 101; rnn.o = 7; rnn.hid_nonlin = Tanh; rnn.h_init = 1x101 gpuArray; inData.BatchSize = 10000; inData.TimeSteps = 100;谢谢迪瓦卡!
  • 对不起,我第一次来这个网站。我已经编辑了我的问题,因此您可以在本地计算机上复制和粘贴并运行代码。再次感谢!

标签: performance matlab function gpu


【解决方案1】:

首先,为了进行正确的基准测试,您确实需要在函数调用内部或之后使用gather。在前一种情况下,您将从函数调用中获得非 gpu 输出,而在后一种情况下,输出将是基于 gpu 的数据类型。现在,回到您的问题,您使用的TimeSteps 很少,因此您可能尝试的任何优化都不会以很大的方式反映出来。这是一个优化的版本,当你增加 Timesteps 时,它会显示出更高的性能 -

function [H,OX] = forward_pass(rnn, inData)

H = zeros(inData.BatchSize, rnn.h, inData.TimeSteps,'gpuArray');

T = reshape(permute(inData.V,[1 3 2]),[],size(inData.V,2))*rnn.W_vh;
H(:,:,1) = tanh(bsxfun(@plus,rnn.h_init * rnn.W_hh,T(1:size(inData.V,1),:)));

for t = 2 : inData.TimeSteps
    H(:,:,t) = tanh( H(:,:,(t-1))*rnn.W_hh + ...
        T((t-1)*size(inData.V,1)+1: t*size(inData.V,1),:));
end

A = reshape(permute(H,[1 3 2]),[],size(H,2))*rnn.W_ho;
OX = permute(reshape(A,size(H,1),size(A,1)/size(H,1),[]),[1 3 2]);

return;

基准测试

测试用例 #1

参数

rnn.v = 11;
rnn.h = 5;
rnn.o = 7;
inData.TimeSteps = 10000;
inData.BatchSize = 10;

结果

---- Original Code :
Elapsed time is 5.678876 seconds.
---- Modified Code :
Elapsed time is 3.821059 seconds.

测试用例 #2

参数

inData.TimeSteps = 50000; (rest are same as in Test Case #1)

结果

---- Original Code :
Elapsed time is 28.392290 seconds.
---- Modified Code :
Elapsed time is 19.031776 seconds.

请注意,这些都是在 GTX 750 Ti 上测试的。

【讨论】:

    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 2016-07-09
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2014-09-12
    • 2019-08-06
    相关资源
    最近更新 更多