fminunc:一个非常奇怪的问题!

10视图(30天)
埃米利亚诺·罗索”class=
埃米利亚诺·罗索 2022年11月7日
编辑: 布鲁诺陈德良 2022年11月9日
我使用fminunc解决最小化问题。Fminunc hundeads调用一个简单的函数,我优化了gpu来提高性能。
这是当我在cpu和gpu之间做个比较单个调用外部fminuc(测试):
TVD = tvd_sim2_mex (x, y, lam幼虫,t);% 0.018秒
TVD = tvd_sim2 (x, y, lam幼虫,t);% 0.003 s 6 x
正如你所看到的是快6倍的性能 cpu。
gpu分析告诉我问题是关于gpu malloc。
这就是发生在我1000次调用这个函数:
i = 1:1000
抽搐
TVD = tvd_sim2_mex (x, y, lam幼虫,t);
mytime (i) = toc;
结束% 0.0005 s 6 x
TVD = tvd_sim2 (x, y, lam幼虫,t);% 0.003秒
正如你所看到的是快6倍的性能 gpu。
现在....我不知道exaclty fminunc内发生函数但粗暴我可以说毫无疑问
两者之间唯一的区别情况tvd_sim2的函数。没有修改fminunc。
gpu总是删除记忆的每一个电话。
函数tvd_sim2 fminunc之前只编译一次。
这是当我使用tvd_sim2和tvd_sim2_mex fminunc之间做个比较
(函数tvd_sim发射fminunc):
抽搐
(y,成本)= tvd_sim (x,林,幼虫,t);运行%些微tvd_sim2
toc
解算器过早地停止。
fminunc停止,因为它超过了迭代的极限,
选项。MaxIterations = 5.000000 e + 01。
运行时间是48.020835秒。
和:
抽搐
(y,成本)= tvd_sim (x,林,幼虫,t);%运行tvd_sim2_mex
toc
解算器过早地停止。
fminunc停止,因为它超过了迭代的极限,
选项。MaxIterations = 5.000000 e + 01。
运行时间是179.953791秒。
在几句话....为什么它慢即使它更快吗?
我认为....在my "1000 times for loop" the variable y 每次总是平等但fminunc变化。
这是由于优化。
但这是一个错误的问题:
i = 1:1000
y =兰德(4096 1);
抽搐
TVD = tvd_sim2_MEX_mex (x, y, lam幼虫,t);
mytime (i) = toc;
结束
disp (”同时,“);
disp(意味着(mytime));
的意思是时间:
5.5624 e-04
事实是gpu内存重新分配每个函数调用,没有区别相同的输入或另一个!
我添加函数运行的截图和gpu。你可以看到所有的时间负责这个函数。
环境变量(广义)可以因此大幅修改gpu的性能运行相同的代码?
或以外的证据是不相同的代码吗?
谢谢!
23日评论
埃米利亚诺·罗索”class=
埃米利亚诺·罗索 2022年11月9日
非凡的! ! !
我必须花时间……
谢谢!

登录置评。

接受的答案

马特·J”class=
马特·J 2022年11月7日
编辑:马特·J 2022年11月7日
如果要我猜,GPU无法实现更快的速度,因为fminunc要求你把GPU计算的结果回到CPU每次调用目标函数。这是因为fminunc做中间的计算必须发生在CPU上。似是而非,CPU-GPU传输的开销,鉴于你的目标的简单性,是控制计算时间。
为什么你的一些时间实验不承担这一点还不清楚,但正如沃尔特说,目前还不清楚您的计时方法是有效的。tic和toc本身是不可靠的,除非你做同步与MATLAB的GPU。你应该被使用 gputimeit 相反,在CUDA代码什么的,我猜( __syncthreads ())。
10评论
埃米利亚诺·罗索”class=
埃米利亚诺·罗索 2022年11月9日
下面的代码:
函数[xden, fval] = tvd_sim (y, lam幼虫,t)
rng默认的%的再现性
[n m] =大小(y);
y0 = y;
ObjectiveFunction = @ (y) tvd_sim2 (y, y0, lam幼虫,t);
选择= optimoptions (“fminunc”,“麦克斯特”,50岁,“ObjectiveLimit”0,“MaxFunEvals”,
正无穷,“TolFun”1 e-06“UseParallel”、假);
[xden, fval] = fminunc (ObjectiveFunction y选项);
结束
函数(TVD) = tvd_sim2 (x, y, lam幼虫,t)% # codegen
coder.gpu.kernelfun
[n m] =大小(y);% x资料片columnwise去噪
diffxx = x (2: n, 1) - x (1: n - 1, 1);
TVD = 1/2。*总和(abs (((x) /((双(abs (y) - t > 0)。* y / t) +双(~(双(abs (y) - t > 0)
。* y / t))) ^ 2) ^ 2)) + lam。*总和(abs (diffxx (2: n - 1, 1) -diffxx (1: n - 1)));
结束
这是cpu timeinit:
t = 0 (1,1);
i = 1:1000
时间t = (@ () tvd_sim2 (x, y, lam幼虫,t));% 0.0014秒
tmean (i) = t;
结束
disp(意味着(t));
1.1071 e-04
0.0012对。
比率e-04 gpu / cpu = 0.0012/1.1071 = 10.83
gpu比cpu x10慢。
这就是我发现:
这是一个很大的错误!
唯一的问题是tic toc给了我一个错误的幻觉,但真的比cpu gpu性能自然慢吗?
所以我就解决了这个神秘仅仅通过溶解一种幻觉?

登录置评。

更多的答案(2)

Ram Kokku”class=
Ram Kokku 2022年11月8日
编辑:沃尔特·罗伯森 2022年11月8日
正如我的同事Hariprasad提到,GPU编码器是一种能力
  1. 分配内存,一旦和重用的后续调用。使用cfg.GpuConfig。EnableMemoryManager = true;启用这个。
  2. 采用MATLAB gpuArray作为输入。你已经这样做了。但这并不总是有帮助。例如,如果GPU编码器选择保持第一次使用一个特定的输入对CPU(由于某种原因),它会产生一个额外的副本。
此外,
  1. 你可以用gpucoder。概要文件(//www.tatmou.com/help/gpucoder/ref/gpucoder.profile.html)找到瓶颈。
  2. 使用细胞数组和结构可能不玩会与GPU编码器把副本。考虑打破细胞分离变量数组元素。
  3. 看看生成的代码,看看GPU编码器能够并行化代码的关键部分。
  4. 如果你愿意分享你的代码,我可以快速浏览。
5个评论
埃米利亚诺·罗索”class=
埃米利亚诺·罗索 2022年11月8日
编辑:埃米利亚诺·罗索 2022年11月8日
“abs没有影响。”
是的,这是真的,我将修改它!
现在我看到你的代码,我将试着验证!
谢谢!

登录置评。


布鲁诺陈德良”class=
布鲁诺陈德良 2022年11月8日
编辑:布鲁诺陈德良 2022年11月8日
只是在黑暗中射击,想知道如果你让UseParallel选项fminunc对还是错?可能是梯度计算是有效的在GPU CPU而不是取决于这个选项。
还你的目标函数不是很微的逻辑,abs,可能是fminunc难以优化,和时间更灵敏数值截断,gpu-mex和cpu-matlab是不同。
顺便说一句目标函数很简单计算分析梯度。
11日评论
布鲁诺陈德良”class=
布鲁诺陈德良 2022年11月9日
“如果这可以帮助”
当然我会记住的 等待 接下来tic-toc GPU最佳化代码。

登录置评。

类别

找到更多的在GPU计算帮助中心文件交换

下载188bet金宝搏


释放

R2020b

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!