【问题标题】:Why do these two instances of a script perform differently?为什么这两个脚本实例执行不同?
【发布时间】:2017-01-10 17:38:02
【问题描述】:

我有 2 个我正在实施的算法实例,我希望它尽可能快,因为它是我需要重复多次的例程的一部分。

想法如下:我有一个n by n by m 矩阵(称为c)并基于它我必须创建一个m by n 矩阵(称为它z)。 z 的每一行是上一行乘以对应的n 乘以cn 切片并归一化的结果。

我的想法是,在 matlab 中最好将代码矢量化并尽可能避免循环,所以我认为第一种方法是我能想到的最快的方法。但事实证明,第二个实现快了大约 15%。谁能解释我为什么?另外,你能告诉我我能不能比第二种方法做得更好吗?

这是两个脚本的虚拟版本(足够接近用于说明目的)

脚本 1

clear all

x = -5:.02:5;
w = 1:.02:11;
t(1,1,:) = w;

n = length(x);
m = length(w);


z      = zeros(m,n);
z(1,:) = exp(-x.^2/2)/sqrt(2*pi);    

a = bsxfun(@times,x,t);
b = bsxfun(@minus,a,x');
c = exp(-bsxfun(@rdivide,b.^2,2*t));

for i = 2:m

    z(i,:) = z(i-1,:)*squeeze(c(:,:,i));
    z(i,:) = z(i,:)/trapz(x,z(i,:));

end

脚本 2

clear all

x = -5:.02:5;
t = 1:.02:11;

n = length(x);
m = length(t);


z      = zeros(m,n);
z(1,:) = exp(-x.^2/2)/sqrt(2*pi);

for i=2:m

    c = exp(-(bsxfun(@minus,x*t(i),x')).^2/(2*t(i)));
    z(i,:) = z(i-1,:)*c;
    z(i,:) = z(i,:)/trapz(x,z(i,:));

end

没想到脚本 1 中的那一行

z(i,:) = z(i-1,:)*squeeze(c(:,:,i));

尽可能慢。

【问题讨论】:

  • 你不需要那个squeezing,对吗?你可能可以在那里保存一些。
  • 是的。我尝试将其删除,但没有任何区别。

标签: performance matlab optimization multidimensional-array


【解决方案1】:

当迭代完成时,索引到 ndim 数组可能会很昂贵。因此,我们可以使用 scratchpad-variable 来避免这种情况。因此,我们可以将script #2 修改为这样的内容 -

z      = zeros(m,n);
tmp    = exp(-x.^2/2)/sqrt(2*pi);
z(1,:) = tmp;
for i=2:m
    tmp = tmp*exp(-(bsxfun(@minus,x*t(i),x')).^2/(2*t(i)));
    tmp = tmp/trapz(x,tmp);
    z(i,:) = tmp;
end

tmp 变量是这里使用的暂存器变量。此外,我们将之前存储为cbsxfun(@minus 结果直接输入到下一步。

运行时测试-

输入:

x = -5:.04:5;
t = 1:.04:11;

时间:

--------------------- With Script #2
Elapsed time is 0.571562 seconds.
--------------------- With Optimized Script
Elapsed time is 0.478028 seconds.

所以,那里有一些边际改进。

【讨论】:

  • 我明白了,聪明!谢谢!我希望真正减少对c 的评估,但我想那里没有什么可做的了。
  • @J.R.C.是的,考虑到其中涉及的trapz 计算,找到该递归形式的封闭形式似乎并不简单。
  • 我认为有必要添加一行:tmp = tmp/trapz(x,tmp);z(i,:) = tmp;
  • 如果我没有trapz怎么办?
  • 啊,你的意思是找到一个实际的分析封闭表达式@divakar?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多