【问题标题】:A nested and expandable for loop in CC中的嵌套和可扩展for循环
【发布时间】:2015-05-16 01:42:49
【问题描述】:

我正在编写一个 C 程序,其中我操作嵌套的 for 循环,一个在另一个循环中,如下所示:

for(i[0] = 0; i[0] < n[0]; i[0]++)
  for(i[1] = 0; i[1] < n[1]; i[1]++)
    for(i[2] = 0; i[2] < n[2]; i[2]++)
      {
       do_lot_of_work(i, n, 3);
      }

如您所见,上面的代码有三个嵌套的for 循环。在我的程序中,它占 3 个维度。但是,我想让我的程序可扩展,它可以根据用户的意愿动态地考虑任意数量的维度;即对于 4 个维度,我希望有四个嵌套的 for 循环,并以 do_lot_of_work(i,n,4) 的身份进行工作。同样,对于任意数量的维度。

我的问题是:如何使上述for 循环的嵌套可扩展?

请注意,为了实现目标,我愿意牺牲内部的for 循环,但希望保留第一个for 循环,以使我的程序与OpenMP 并行。

【问题讨论】:

  • 我不认为 recursion 在你的菜单上?
  • 是的,但我担心如果使用递归函数我可能不会使用 OpenMP。但是,无论如何,从目前的答案看来,我仍然可以在最内层循环使用 OpenMP。无论如何,谢谢您指出!
  • 当然。递归确实是一种优雅的方法,我认为你没有理由不能用 OpenMP 括起那个 for 循环(已经有一段时间了,但我认为它可以工作)。祝你好运。

标签: c for-loop nested expandable


【解决方案1】:

当编译时不知道嵌套级别时,使用递归也可以达到同样的效果:

void do_work(int i[], int n[], int pos, int size) {
    if (pos == size) {
        // All i-s are set - we are ready to roll
        do_lot_of_work(i, n, size);
    } else {
        for (i[pos] = 0 ; i[pos] < n[pos] ; i[pos]++) {
            do_work(i, n, pos+1, size);
        }
    }
}

【讨论】:

    【解决方案2】:

    使用递归函数。

    void tons_of_work( int i[], int n[], int dims ) {
        loop_level( 0, i, n, dims );
    }
    
    void loop_level( int level, int i[], int n[], int dims ) {
        if ( level == dims ) {
            do_lot_of_work( i, n, dims );
        } else {
            int * ilevel = & i[ level ];
            for ( *ilevel = 0; *ilevel != n[ level ]; ++ *ilevel ) {
                loop_level( level + 1, i, n, dims );
            }
        }
    }
    

    loop_level 调用自身产生嵌套循环,直到到达最内层循环级别。然后它开始做“真正的”工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      相关资源
      最近更新 更多