大家好我正致力于图像处理,并在 MATLAB 中编写了一小段代码。代码很慢。
我在这里提供我的代码片段
for i=1:10
//find c1,c2,c3
//c1 c2 and c3 change at each iteration
u = (1./((abs(P-c1))^m) + 1./((abs(P-c2))^m) + 1./((abs(P-c3))^m));
u1 = 1./((abs(P-c1))^m)./u;
u2 = 1./((abs(P-c2))^m)./u;
u3 = 1./((abs(P-c3))^m)./u;
end
让我在这里解释变量:
P,u,u1,u2 and u3 are all matrices of size 512x512
c1,c2 and c3 are constants of dimension 1x1
m is a constant with value = 2
我想在循环中重复这个操作(比方说10次)。但是我的代码很慢。
剖析器的结果如下:
该计划的总运行时间为4.6秒。然而,上面列出的四个步骤本身占80%的时间。
所以我想让我的代码运行更快。 我的第一次编辑
我更改的代码段
for i=1:10
//find c1 and c2
//c1 and c2 changes at each iteration
a=((abs(P-c1))^m);
b=((abs(P-c2))^m);
c=((abs(P-c3))^m);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
end
现在程序在2.47秒内计算上述步骤的计算时间如下:
所以这比我的第一种方法快得多。
第二次修改 因为我= 1:10 //找到c1,c2,c3 // c1 c2和c3在每次迭代时都会发生变化
a=(P-c1).*(P-c1);
b=(P-c2).*(P-c2);
c=(P-c3).*(P-c3);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
end
现在程序计算时间为0.808秒。
上述四个步骤非常快速地计算出来。
我相信它可以做得更快。你能帮助我进一步优化 我的代码。 对于大于512的矩阵,如1024,2048或类似物,它将非常有用。
提前致谢。
答案 0 :(得分:1)
第一个建议是:
如果 m = 2 并且没有变化,为什么不尝试这些替代方案:
A*A
如果 m = 2 ,那么你真的需要 abs 吗?
你正在做的这部分
1./a
比
快a.^(-1)
所以我认为这部分没有更好的选择。
你可以尝试的另一件事就是这个。而不是:
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
你可以拥有:
u = (x + y + z);
u1 = 1./(a.*u);
u2 = 1./(b.*u);
u3 = 1./(c.*u);
这种方式我想通过删除3个变量来加快一点。但代码变得不那么可读了。
答案 1 :(得分:1)
您当前的代码是:
a=((abs(P-c1))^m);
b=((abs(P-c2))^m);
c=((abs(P-c3))^m);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
首先,要认识到绝对值函数是乘法的。所以|AB| = |A|x|B|
。现在,abs(P-C1)^m
相当于abs( (P-C1)^m )
。
初步看一眼它表明瓶颈中的一些计算可以重复使用。具体来说,由于c1
,c2
和c3
是常量,如果您尝试重用它们(以牺牲额外内存为代价),计算可以加快一点。
temp_P2 = P*P;
temp_PCA = P*ones(size(P));
temp_PCB = ones(size(P))*P;
a = abs(temp_P2 - c1*temp_PCA - c1*temp_PCB + c1^2 * length(P))
temp_PCA
和temp_PCB
的计算也可以避免,因为乘以常数矩阵总是等于构造具有常数行或列的秩1矩阵。
我并不认为任何这些修改都会加快您的代码速度,但绝对值得尝试。