首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用MATLAB的GPU功能计算和(a.*exp(b.*c),1)的有效方法

问利用MATLAB的GPU功能计算和(a.*exp(b.*c),1)的有效方法
EN

Stack Overflow用户
提问于 2020-02-05 21:10:53
回答 1查看 163关注 0票数 4

我有GPU加速MATLAB代码,花费了80%-90%的计算时间。

代码语言:javascript
复制
sum(a.*exp(b.*c),1)

哪里

代码语言:javascript
复制
size(a) = [n 1]
size(b) = [n 1]
size(c) = [1 m]

n可以被选择为任意大(在内存约束内)

5000 < m < 20000

我想加快速度,不仅仅是使用gpuArrays (双精度大约是17倍)。

基准测试

使用Matlab2018b和NVIDIA P100 GPU,我运行了以下脚本,旨在找到n的最佳大小。它表明,与使用双精度的CPU (双套接字英特尔XeonE5-2650v2)相比,我实现了17x的加速。我是否可以通过做一些更高级的事情来改进这一点,比如使用GPU编码器,甚至使用共享内存或纹理内存,如下面所述?https://uk.mathworks.com/help/parallel-computing/examples/accessing-advanced-cuda-features-using-mex.html

代码语言:javascript
复制
%% Optimisation MWE

nVec = 1000:1000:60000; % Vector of candidate n values
m = 5000;

f1 = figure(1);
ax(1) = subplot(3,1,1);
ax(2) = subplot(3,1,2);
ax(3) = subplot(3,1,3);

% Preallocate time outputs
t = nan(length(nVec),3);
speedupGPU = nan(length(nVec),2);

% Loop over candidate n values
for n = 1:length(nVec)

    %% CPU code
    a = rand(nVec(n),1);
    b = rand(nVec(n),1);
    c = rand(1,m);

    f1 = @() sum(a.*exp(b.*c),1);

    t(n,1) = timeit(f1,1);

    %% GPU code (double precision)
    a = gpuArray(a);
    b = gpuArray(b);
    c = gpuArray(c);

    f2 = @() sum(a.*exp(b.*c),1);

    t(n,2) = gputimeit(f2);

    %% GPU code (single precision)
    a = single(a);
    b = single(b);
    c = single(c);

    f3 = @() sum(a.*exp(b.*c),1);

    t(n,3) = gputimeit(f3);

    %% Calculate speedup
    speedupGPU(n,1) = t(n,1)/t(n,2);
    speedupGPU(n,2) = t(n,1)/t(n,3);

    %% Plot
    plot(ax(1),nVec,t,'.-')             % Plot compute time
    plot(ax(2),nVec,t./nVec(:),'.-')    % Plot normalised compute time
    plot(ax(3),nVec,speedupGPU,'.-')    % Plot Speedup

    %% Label plots
    xlabel(ax(1),'n')
    ylabel(ax(1),'Time')
    legend(ax(1),'CPU','GPU double','GPU single')

    xlabel(ax(2),'n')
    ylabel(ax(2),'Normalised Time')
    legend(ax(2),'CPU','GPU double','GPU single')

    xlabel(ax(3),'n')
    ylabel(ax(3),'Speedup')
    legend(ax(3),'CPU/GPU double','CPU/GPU single')

    drawnow

end

这将产生以下图(顶部:执行时间随n(越小越好)、中间:n个规范化的执行时间(越小越好)、底部:相对于CPU的加速(越大越好):

​

​

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-06 07:16:31

我意识到它可能不会给您提供所要的加速比,但是要使这段代码更有表现力,一种方法是使用矩阵乘法来消除sum:

代码语言:javascript
复制
sum(a.*exp(b.*c),1) --> a.'*exp(b.*c)

在我的系统中,这导致了加速,从10 ~15。

我还要提到的是,对于n的最低值,我还将数组乘法(.*)替换为矩阵乘法(*):a.'*exp(b.*c) --> a.'*exp(b*c),从而得到了20的加速比。

在R2019b,Win10,GTX660上进行了测试。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60084167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档