【问题标题】:Remove the cycles删除循环
【发布时间】:2021-03-24 05:53:00
【问题描述】:

我需要摆脱我的 Matlab 代码中的循环。在此过程中,我遇到了以下问题。这是部分代码

Nx=11; Ny=11; 
A=rand(Ny,Nx);
A1=A;
 
       for j=2:Ny-1      
       for i=2:Nx-1
          A(j,i)=A(j,i-1);
       end;
       end;
 
A1(2:Ny-1,2:Nx-1)=A1(2:Ny-1,1:Nx-2);
 
A2=A-A1;

我知道A 不等于A1。右侧的j-1 索引情况与此相同。但是,如果我们采用索引i + 1j + 1,那么一切正常。

【问题讨论】:

  • “我需要去除我的 Matlab 代码中的循环。”为什么?这是“循环很慢的常识”吗?或者您是否通过分析器确定此特定循环是您代码中的瓶颈? MATLAB 中的循环已经很多年没有变慢了。当然,向量化代码有时仍然更快,但收益微乎其微。您需要先分析您的代码,然后再决定将时间和精力投入到哪些代码上以加快速度。
  • 我需要执行此过程,因为我使用并行 GPU 计算。 CPU 代码在速度适中的网格大小的情况下与循环配合得很好。相反,代码应该为 GPU 计算向量化以获得令人印象深刻的加速。

标签: matlab loops for-loop matrix linear-algebra


【解决方案1】:

问题相对简单:您将A1 的列一次全部向右移动(将第1 列复制到第2 列并在此过程中丢弃Nx-1 列),而您的for 循环将A 列在右侧,一次从左到右。这意味着首先用第 1 列的内容覆盖第 2 列,然后用第 2 列覆盖第 3 列,依此类推,最终得到第一列的Nx-1 副本。 (当我谈到复制/移动/丢弃列时,我指的是它们的值从行 2 到行 Ny-1。)

如您所见,如果您修改循环以将列向左移动,即

for j=2:Ny-1
  for i=2:Nx-1
    A(j,i)=A(j,i+1);
%...

那么这个问题就不会发生,因为您有机会读取任何给定列的原始内容并将它们保存在其他位置,然后再用新值覆盖它们。

for 循环从左到右遍历列时,上述所有结果都适用。如果你颠倒迭代的方向,即

%...
  for i=Nx-1:-1:2
    A(j,i)=%...

然后右移列按预期工作,而将它们向左移动会产生虚假结果。

【讨论】:

  • 感谢您清晰简洁的解释!
猜你喜欢
  • 2013-04-08
  • 2016-10-25
  • 2020-07-13
  • 2021-01-20
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多