请问这个程序为什么越来越慢?

novicer
novicer 09月09日 字数 287

u2 = exp(i.*zeros(8192,8192));

for ite1 = 1:800

for ite2 = 1:900

u = exp(i.*sqrt(xy_2d- z_2d(ite1,ite2)));

u2 = u2.*u;

end

end

这个程序越来越慢,请问是什么原因?请问有什么办法加速或者让他匀速运行吗?

MathTools 数学工具
17 个回复
zszqzzzf
炼狱天使——反者道之动 09月09日

prod

【 在 novicer (novicer) 的大作中提到: 】

: u2 = exp(i.*zeros(8192,8192));

: for ite1 = 1:8192

:      for ite2 = 1:8192

: ...................

novicer
novicer 09月09日

能稍微详细说下怎么该吗?多谢!

u2 = exp(i.*zeros(8192,8192));

for ite1 = 1:800

for ite2 = 1:900

u = exp(i.*sqrt(xy_2d- z_2d(ite1,ite2)));

u2 = u2.*u;

end

end

【 在 zszqzzzf 的大作中提到: 】

: prod

zszqzzzf
炼狱天使——反者道之动 09月09日

u2整个提取到循环外,可以用prod,对矩阵求累积。

双重循环计算也是慢的。如果你能做到消灭两个for,改成矩阵运算,速度可以提高百倍。

cellfun翻一翻看看能不能就取代ite1和ite2,……

【 在 novicer (novicer) 的大作中提到: 】

: 标  题: Re: 请问这个程序为什么越来越慢?

: 发信站: 水木社区 (Thu Sep  9 09:30:36 2021), 站内

: 能稍微详细说下怎么该吗?多谢!

: u2 = exp(i.*zeros(8192,8192));

: for ite1 = 1:800

:   for ite2 = 1:900

:      u = exp(i.*sqrt(xy_2d- z_2d(ite1,ite2)));

:      u2 = u2.*u;

:   end

: end

: 【 在 zszqzzzf 的大作中提到: 】

: : prod

: --

novicer
novicer 09月09日

整个u2提到循环外,怎么保存u呢?u本身是一个800*900的矩阵,如果要保存,循环之后好像是8192*8192*800*900个元素

【 在 zszqzzzf 的大作中提到: 】

: u2整个提取到循环外,可以用prod,对矩阵求累积。

: 双重循环计算也是慢的。如果你能做到消灭两个for,改成矩阵运算,速度可以提高百倍。

: cellfun翻一翻看看能不能就取代ite1和ite2,……

: ...................

zszqzzzf
炼狱天使——反者道之动 09月09日

一切都有代价,需要程序员根据数据特性灵活处置。

u是稀疏的话,可以用稀疏矩阵来存。single比double小,int就更好。

总之你忍受不了慢的话,干掉for循环是常用方法。

穷尽一切办法还太慢,换机器。

【 在 novicer (novicer) 的大作中提到: 】

: 整个u2提到循环外,怎么保存u呢?u本身是一个800*900的矩阵,如果要保存,循环之后好像是8192*8192*800*900个元素

novicer
novicer 09月09日
shaolimin
魏晋风度 09月09日
shaolimin
魏晋风度 09月09日

temp = zeros(8192,8192);

for ite = 1:720000

temp = temp + i*sqrt(xy_2d - z_2d(ite));

end

u2 = exp(temp);

【 在 novicer 的大作中提到: 】

: u2 = exp(i.*zeros(8192,8192));

: for ite1 = 1:800

:    for ite2 = 1:900

: ...................

novicer
novicer 09月09日

非常感谢!请问2维变1维会更快吗?

循环里面的i好像可以提到循环外?

【 在 shaolimin 的大作中提到: 】

: temp = zeros(8192,8192);

: for ite = 1:720000

:   temp = temp + i*sqrt(xy_2d - z_2d(ite));

: ...................

zszqzzzf
炼狱天使——反者道之动 09月09日

temp =arrayfun(@(ite) sum(i*sqrt(xy_2d-z2d(ite)),[1:720000]);

【 在 shaolimin (魏晋风度) 的大作中提到: 】

: 标  题: Re: 请问这个程序为什么越来越慢?

: 发信站: 水木社区 (Thu Sep  9 13:06:52 2021), 站内

: temp = zeros(8192,8192);

: for ite = 1:720000

:   temp = temp + i*sqrt(xy_2d - z_2d(ite));

: end

: u2 = exp(temp);

: 【 在 novicer 的大作中提到: 】

: : u2 = exp(i.*zeros(8192,8192));

: : for ite1 = 1:800

: :    for ite2 = 1:900

: : ...................

: --

shaolimin
魏晋风度 09月09日

2维变1维是为了减少一个循环。

循环里面的i确实可以提到循环外。

【 在 novicer 的大作中提到: 】

: 非常感谢!请问2维变1维会更快吗?

: 循环里面的i好像可以提到循环外?

novicer
novicer 09月09日

如果内存足够大,能不能把后一个矩阵变成(8192*8192) * (800*900)的二维矩阵,从而不用for循环?

【 在 shaolimin 的大作中提到: 】

: 2维变1维是为了减少一个循环。

: 循环里面的i确实可以提到循环外。

shaolimin
魏晋风度 09月09日

如果内存足够大,试试以下代码。

temp1 = repmat(xy_2d, [1 1 720000]);

temp2 = permute(repmat(z_2d(:)*ones(1, 8192), [1, 1, 8192]), [3 2 1]);

u2 = exp(sum(i*sqrt(temp1 - temp2), 3));

【 在 novicer (novicer) 的大作中提到: 】

: 标  题: Re: 请问这个程序为什么越来越慢?

: 发信站: 水木社区 (Thu Sep  9 14:54:07 2021), 站内

: 如果内存足够大,能不能把后一个矩阵变成(8192*8192) * (800*900)的二维矩阵,从而不用for循环?

: 【 在 shaolimin 的大作中提到: 】

: : 2维变1维是为了减少一个循环。

: : 循环里面的i确实可以提到循环外。

: :

: --

novicer
novicer 09月10日
novicer
novicer 09月10日
shaolimin
魏晋风度 09月10日

xource_temp2(:, :, k)中的元素都相等,且等于xsource2d(k);

yource_temp2(:, :, k)中的元素都相等,且等于ysource2d(k);

k从1到size1*size2。

你检查一下是不是这样的。

【 在 novicer 的大作中提到: 】

: 非常感谢!不知道什么地方错了?

: 原for循环:

: for ite1 = 1:size1*size2

: ...................

novicer
novicer 09月10日
novicer
novicer 09月10日
novicer
novicer 09月10日

写了个3重循环,是这样的

diffx = xsource_temp2(ite1,ite2,ite3) - xsource2d(ite3);

diffy = ysource_temp2(ite1,ite2,ite3) - ysource2d(ite3);

diffx和diffy都是0

【 在 shaolimin 的大作中提到: 】

: xource_temp2(:, :, k)中的元素都相等,且等于xsource2d(k);

: yource_temp2(:, :, k)中的元素都相等,且等于ysource2d(k);

: k从1到size1*size2。

: ...................