【问题标题】:Optimizing a Vectorized Matlab Function优化向量化 Matlab 函数
【发布时间】:2012-10-15 18:10:57
【问题描述】:

当我运行分析器时,它告诉我最耗时的代码是函数vdist。它是一个程序,可以测量地球上两点之间的距离,将地球视为椭球体。代码看起来很标准,我不知道在哪里以及如何改进它。最初的 cmets 说,它已经被矢量化了。是否有其他语言的对应物可以用作 MEX 文件。我想要的只是时间效率方面的改进。这是 Matlab FEX 代码的链接。

http://www.mathworks.com/matlabcentral/fileexchange/8607-vectorized-geodetic-distance-and-azimuth-on-the-wgs84-earth-ellipsoid/content/vdist.m

函数是从循环中调用的——(你可以在这里找到最耗时的函数)

              109 for i=1:polySize 
              110    % find the two vectors needed
       11755  111    if i~=1 
0.02   11503  112        if i<polySize 
0.02   11251  113         p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(i+1,:);    
         252  114        else 
         252  115         p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(1,:); %special case for i=polySize 
         252  116        end 
         252  117    else 
         252  118         p0=Polygon(i,:); p1=Polygon(polySize,:); p2=Polygon(i+1,:); %special case for i=1 
         252  119    end 
 0.02  11755  120    Vector1=(p0-p1); Vector2=(p0-p2); 
 0.06  11755  121    if ~(isequal(Vector1,Vector2) || isequal(Vector1,ZeroVec) || isequal(Vector2,ZeroVec)); 
              122        %determine normals and normalise and
 0.17  11755  123        NV1=rotateVector(Vector1, pi./2); NV2=rotateVector(Vector2, -pi./2); 
 0.21  11755  124        NormV1=normaliseVector(NV1); NormV2=normaliseVector(NV2); 
              125        %determine rotation by means of the atan2 (because sign matters!)
       11755  126        totalRotation = vectorAngle(NormV2, NormV1); % Bestimme den Winkel totalRotation zwischen den normierten Vektoren 
       11755  127      if totalRotation<10 
       11755  128          totalRotation=totalRotation*50; 
       11755  129      end 
0.01   11755  130      for res=1:6 
0.07   70530  131         U_neu=p0+NV1; 
17.01  70530  132         [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
0.02   70530  133         a12=a12+1/6.*res*totalRotation; 
       70530  134         ddist=1852*safety_distance; 
4.88   70530  135         [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12); 
0.15   70530  136         extendedPoly(f,:)=[lon2,lat2];f=f+1; 
< 0.01 70530  137      end 
       11755  138    end 
       11755  139 end 

【问题讨论】:

  • 该函数中有哪些行会成为瓶颈?您还可以向我们展示如何调用此函数的示例。如果您在循环中使用标量调用它,那么您将不会从矢量化代码中获得任何好处。
  • 确保你提供矢量化输入,这可能并不容易提高这个算法的一般性能,但也许你可以剪掉一些你不使用的部分?
  • @slayton- 我已经包含了上面的调用循环。就瓶颈而言,它不像几条线一直在占用,但它有点分散。是的,有些行比其他行花费更多时间,但一行的最高值是整个函数的 10%。

标签: performance matlab optimization vectorization mex


【解决方案1】:

无论我多么努力地研究已发布的代码,我都看不出为什么对vdist 的调用是在循环内进行的。

当我尝试优化循环内的代码块时,我寻找的一件事是不变的语句,即每次调用都相同,因此可以从循环中取出.

看着

130      for res=1:6 
131         U_neu=p0+NV1; 
132         [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
133         a12=a12+1/6.*res*totalRotation; 
134         ddist=1852*safety_distance; 
135         [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12); 
136         extendedPoly(f,:)=[lon2,lat2];f=f+1; 
137      end 

我明白了

  • 在l131中变量p0,NV1只出现在rhs上,而且它们只出现在rhs循环内的其他地方,所以这个语句是循环不变的,可以从循环中取出;也许只节省一点时间;
  • 再次在 l134 中,我看到另一个循环不变语句,可以再次将其从循环中取出,以节省一点时间;
  • 但后来我开始仔细观察,我看不出为什么调用vdist 的l132 也在循环内。该赋值的 rhs 上的任何值都没有在循环中被修改(U_neu 除外,但我已经将它从循环中移除了)。

把剩下的东西整理一下,这就是我最终的结果:

U_neu=p0+NV1; 
[pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
ddist=1852*safety_distance; 
for res=1:6 
   extendedPoly(f,:) = vreckon(p0(:,2),p0(:,1),ddist, a12+1/6.*res*totalRotation); 
   f=f+1; 
end 

【讨论】:

  • @Mark- 非常感谢您的回复,非常有帮助。现在,每次我看到一个循环时,我都会在里面寻找不变的语句。虽然编写了代码,但性能不是问题,这就是为什么它在那里有一些不变的语句。再次感谢!
【解决方案2】:

您可以选择重写此 FEX 文件,以便您可以在 GPU 上使用它。例如,一个平滑的方法是一个名为 Jacket 的工具箱。

【讨论】:

  • @nate- 我的电脑(i7 3.4Ghz,8GB RAM)没有专用显卡。它具有内置显卡的 Intel HD 4000。它是迄今为止最好的英特尔,但我猜它与夹克不兼容。但我有一个问题,我如何确保 MATLAB 是否充分利用了提供给它的资源?
  • 从 matlab 的内置函数中获得的东西是有限度的。有些是高度优化的,比你得到的任何东西都快,有些则不是。由于 vdist 是用户构建的功能,您可以将其拆开,看看您是否真的需要它查看的所有警告\消息\不同情况,并获得最适合您需求的更优化版本。有时使用单而不是双会提高速度,有时使用 int16 等。鉴于您使用的机器,您不能使用夹克,如果您限制自己使用 matlab,那么它可能会尽可能好......
猜你喜欢
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 2015-05-31
  • 1970-01-01
相关资源
最近更新 更多