为啥在这段代码中 CPU 运行速度比 GPU 快?

Posted

技术标签:

【中文标题】为啥在这段代码中 CPU 运行速度比 GPU 快?【英文标题】:Why does CPU run faster than GPU in this code?为什么在这段代码中 CPU 运行速度比 GPU 快? 【发布时间】:2022-01-19 14:52:13 【问题描述】:

我正在尝试使用gpuArray 来加快我的计算速度。但是,下面的代码并非如此。

for i=1:10
    calltest;
end

function [t1,t2]=calltest
N=10;
tic
u=gpuArray(rand(1,N).^(1./[N:-1:1]));
t1=toc
tic
u2=rand(1,N).^(1./[N:-1:1]);
t2=toc
end

我在哪里

t1 =

   4.8445e-05


t2 =

   1.4369e-05

我有一块 Nvidia GTX850M 显卡。我是否错误地使用了gpuArray?这段代码被包裹在一个函数里面,这个函数被循环调用了上千次。

【问题讨论】:

请注意,timeit 将返回更可靠的结果。 您正在将最终结果复制到 GPU,这不是您想要的。你应该做类似u=gpuArray(rand(1,N)).^(1./gpuArray([N:-1:1]))); (untested) 查看gpuArray 文档。 实际上使用您建议的方法要慢得多。我编辑了代码,使用gpuArray 时,似乎循环和调用函数使其变慢!有什么想法吗? 将数据传输到 GPU 可能需要一些时间。您可以通过预先传输来仅计时计算时间。 【参考方案1】:

为什么?因为两者都有a) 小问题规模&b) 不是“数学密集”的 GPU 内核

比较的方法模糊了问题的根源

第 0 步:将数据集(向量)创建与被测部分分开:

N = 10;
R = rand( 1, N );
tic; < a-gpu-based-computing-section>; GPU_t = toc
tic; c = R.^( 1. / [N:-1:1] );         CPU_t = toc

第一步:测试缩放:

只尝试 10 个元素,不会使观察变得清晰,因为 开销天真 formulation of Amdahl Law 没有明确强调增加的时间,花费在基于 CPU 的GPU 内核组装和传输 +(CPU 到 GPU + GPU 到 CPU)数据处理阶段。如果与 a) 一个真正大规模的矢量/矩阵 GPU 内核处理(N ~10 显然不是 或b) 确实是“数学密集”的 GPU 内核处理,R.^() 显然不是 所以, 不要责怪 GPU 计算获得了必须做的部分(开销),因为如果没有这些先前的附加组件,它就无法正常工作(并且 CPU 可能在相同的时间内产生最终结果 - QED )

每个 CPU-GPU-CPU-工作流部分的细粒度测量:

N = 10;                                     %% 100, 1000, 10000, 100000, ..
tic; CPU_hosted     = rand( N, 'single' );  %% 'double'
CPU_gen_RAND        = toc

tic; GPU_hosted_IN1 = gpuArray( CPU_hosted );
GPU_xfer_h2d        = toc

tic; GPU_hosted_IN2 = rand( N, 'gpuArray' );
GPU_gen__h2d        = toc

tic; <kernel-generation-with-might-be-lazy-eval-deferred-xfer-setup>;
GPU_kernel_AssyExec = toc

tic; CPU_hosted_RES = gather( GPU_hosted_RES );
GPU_xfer_d2h        = toc

【讨论】:

您确定要在 GPU 上执行任何计算吗? 虽然我不确定,如果 MathWorks 实现测试生成的 GPU 内核是否有效地成为指令数据集上的 NOP/身份运算符,我很确定 a)b) 成立。然而,GPU 内核 + ( h2d & d2h ) 数据传输的代码相关和数据相关开销仍然存在。您的观点在系统上是正确的,而我怀疑(由于其巨大的计算成本)MathWorks 是否执行预测试,有效地预验证所有 GPU 内核确实在每个要输入的数据元素上输出一个标识(b4捷径 GPU-step) 你不是。 gpuArray 将东西放入 GPU。您的代码首先执行R.^( 1. / [N:-1:1] ),然后将结果放入GPU。你说的对,但你的代码错了

以上是关于为啥在这段代码中 CPU 运行速度比 GPU 快?的主要内容,如果未能解决你的问题,请参考以下文章

在 GPU 上训练比在 CPU 上慢得多 - 为啥以及如何加快速度?

为啥 OpenCV Gpu 模块的性能比 VisionWorks 快?

写入 Linux 管道的速度比文件快,但在内核级别,为啥?

为啥字典比列表快得多?

为啥在这段代码中向量比指针使用更少的内存?

为啥在 GPU 中执行方法的时间比在混合器项目中的 CPU 中执行的时间更多?