【问题标题】:Improving efficiency of a C loop [closed]提高 C 循环的效率
【发布时间】:2018-04-18 23:21:07
【问题描述】:

我有一些可以工作的 c 代码,希望提高效率。我知道最好避免循环中的 if 语句,但是我正在努力解决这个问题。谁能建议我如何使以下代码更有效率?

for(iy=0;iy<Ny;iy++) {
for(ix=0;ix<Nx;ix++) {


    if (ix==0) {
      pudx = (u[1][iy] + u[Nx-1][iy] - 2.0*u[0][iy])/(calc1);   
    } else if (ix==Nx-1) {
      pudx = (u[0][iy] + u[Nx-2][iy] - 2.0*u[Nx-1][iy])/(calc1);  
    } else {
      pudx = (u[ix+1][iy] + u[ix-1][iy] - 2.0*u[ix][iy])/(calc1);
    }

    if (iy==0) {
      pudy = (u[ix][1] + u[ix][Ny-1] - 2.0*u[ix][0])/(calc2);    
    } else if (iy==Ny-1) {
      pudy = (u[ix][0] + u[ix][Ny-2] - 2.0*u[ix][Ny-1])/(calc2);   
    } else {
      pudy = (u[ix][iy+1] + u[ix][iy-1] - 2.0*u[ix][iy])/(calc2);
    }


    u_new[ix][iy] = 2.0*u[ix][iy] - u_old[ix][iy] + calc*(pudx+pudy);

  }
}

我知道这种优化可以通过编译器完成,但我想通过 -o 标志提高效率(无编译器优化)。

【问题讨论】:

  • 您可以优化循环中的比较,但我怀疑即使是优秀的编译器也可以做到这一点。代码中代价高昂的部分是浮点运算。良好的优化通常基于对数据信息的巧妙利用。由于我们对此一无所知,没有什么比优化编译器更好的了。
  • Nx 和 Ny 有多大?
  • 关于改进其他工作代码的问题更适合Code Review,但请务必遵循他们的内容指南。
  • 您可以做的另一件事是在循环外取calc1 和calc2 的倒数,然后在循环内用乘法替换除法。结果可能不会完全相同,但应该非常接近。
  • 我看不出这个问题有什么不清楚的地方,(除了 why OP 不想使用编译器优化之外。)这对我来说似乎很简单: “我可以应用哪些手动优化来使此代码在编译器优化不可用或不需要的环境中运行得更快?”

标签: c loops optimization


【解决方案1】:

在@JohnBollinger 之后:(显然未经测试)


unsigned ix, iy;
for(iy=0;iy<Ny;iy++) {
  unsigned  yl,yh;

  yl = (iy -1) %Ny; yh = (iy +1) %Ny;
  for(ix=0;ix<Nx;ix++) {
      unsigned xl,xh;

      xl = (ix -1) %Nx; xh = (ix +1) %Nx;
      yl = (iy -1) %Ny; yh = (iy +1) %Ny;

      pudx = (u[xh][iy] + u[xh][iy] - 2.0*u[ix][iy])/(calc1);   
      pudy = (u[ix][yh] + u[ix][yl] - 2.0*u[ix][iy])/(calc2);    

    u_new[ix][iy] = 2.0*u[ix][iy] - u_old[ix][iy] + calc*(pudx+pudy);

  }
}

【讨论】:

  • 另外:yl 和 yh 的计算看起来像是可以从内部 for 循环中提升出来,不是吗?
  • 另外:2.0*u[ix][iy] 这个词出现了三次,我认为可以提升到一个临时变量中。
  • @JVMATL :你是对的。已更正。让不变量脱离循环是下一个问题......
  • 我讨厌这样的问题。如果没有分析器和一些硬数字,人们只能猜测我们是否正在优化某项繁忙的工作,同时在其他地方进行 I/O xfer 使其全部静音。
  • 在 pudx temp 中,u[xh][iy] + u[xh][iy] 是 2 * u[xh][iy]。也同意这感觉像是早期的预计算。
猜你喜欢
  • 2015-10-08
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多