在Matlab中使用GPU的convn的性能

时间:2014-03-10 15:59:33

标签: matlab gpgpu

我找到了一个相关的 stackoverflow中的 question

它无法解决我的问题。我发现当维度m很小时,使用GPU的convn比使用CPU的convn更糟糕。我使用了以下测试代码:

m=28;
n=10;
%m=100;
%n=100;
Nsample = 50;
k=5;
x1 = gpuArray.rand(m,m,Nsample,'single');
x2 = gpuArray.rand(k,'single');
tic;
for i=1:n
    gc=convn(x1 , x2 , 'valid');
end
toc

x1 = rand(m,m,Nsample,'single');
x2 = rand(k,'single');
tic;
for i=1:n
    c=convn(x1,x2,'valid');
end
toc

对于不同的m值,性能不同:

当m = 28时,     经过时间为0.076827秒。     经过的时间是0.020734秒。

当m = 100时,     经过时间为0.086314秒。     经过的时间是0.234197秒。

当m = 200时,     经过时间为0.077589秒。     经过的时间是0.243595秒。

当m很小时,似乎Matlab可以优化GPU代码。我想也许这取决于IO成本。

当m很小时,有没有办法优化代码?

非常感谢你们。

----------------------- 额外实验结果(11/03/2014) ------- ---------------------

您好

感谢您的回复。

我和我的同事做了额外的实验,我们发现了一些额外的结果。简而言之,我们在Matlab中观察到两个问题:

  1. 垃圾收集需要很长时间。
  2. 当我不断分配新变量时会抛出错误。
  3. 问题1

    我使用了以下代码:

    timel=[];
    for i=1:10;
        m1 = 1000;    m2 = 1000;    Nsample = 50;    n=10;    k=5;
        tic;
        x1 = gpuArray.rand(m1,m2,Nsample,'single');
        x2 = gpuArray.rand(k,'single');
        clear x1 x2;
        time = toc;
        timel = [timel , time];
    end
    timel
    

    结果是:

    timel =   0.0646    0.0579    0.0563    0.0566    0.0572    0.0571    0.0560    0.0574    0.0573    0.0582
    

    似乎收集垃圾记忆空间需要很长时间。

    对于CONVN的运行时间,如果我使用以下代码添加函数convn,但结果保存到gc

    timel=[];
    for i=1:10;
        m1 = 1000;    m2 = 1000;    Nsample = 50;    n=10;    k=5;
        x1 = gpuArray.rand(m1,m2,Nsample,'single');
        x2 = gpuArray.rand(k,'single');
    
        % running time of CONVN
        tic;        
        gc = convn(x1,x2,'valid');        
        %clear gc;
        time = toc;
    
        clear x1 x2;
        timel = [timel , time];
    end
    timel
    

    运行时间是:

     timel = 0.0643    0.1215    0.0075    0.2517    0.0075    0.2504    0.0075    0.2500    0.0075    0.0075
    

    运行时间不稳定:从0.00750.2517

    如果我取消注释行clear gc;,那么运行时间非常稳定,如下所示:

    timel = 0.0627    0.0657    0.0634    0.0634    0.0623    0.0623    0.0629    0.0632    0.0632    0.0622
    

    它表示convn的运行时间很快,但内存收集是瓶颈。

    有谁知道我如何使用修复gpu内存的一部分而没有内存集合,例如c样式代码:

    `convn(x1,x2,&gc,'valid')`
    

    问题2

    我使用了以下代码:

    %% test Memory Allocation
    timel=[];
    for i=1:10000;
        m1 = 1000;    m2 = 1000;    Nsample = 50;    n=10;    k=5;
        tic;
        x1 = gpuArray.rand(m1,m2,Nsample,'single');
        %clear x1;
        time = toc;
        timel = [timel , time]
    end  
    

    结果显示分配新内存的成本时间非常小,但在几次循环后会引发一个错误:

    Error using gpuArray.rand
    An unexpected error occurred trying to launch a kernel. The CUDA error was:
    the launch timed out and was terminated
    Error in test (line 20)
            x1 = gpuArray.rand(m1,m2,Nsample,'single');
    

    这是合理的,因为我分配了很多gpu记忆。但更糟糕的是,如果我使用

    clear all;
    

    我会得到额外的警告,如下:

    Warning: An unexpected error occurred during CUDA execution. The CUDA error was:
    CUDA_ERROR_LAUNCH_TIMEOUT 
    Warning: An unexpected error occurred during CUDA execution. The CUDA error was:
    CUDA_ERROR_LAUNCH_TIMEOUT 
    

    在重置GPU设备之前,我仍无法分配新的GPU内存,使用:reset(gpuDevice()) 当前一个错误引发时,似乎Matlab无法跟踪所有内存,而我无法清除所有已分配的内存。

0 个答案:

没有答案