【问题标题】:Any fast search algorithms for nested for loops?任何用于嵌套 for 循环的快速搜索算法?
【发布时间】:2014-04-26 20:06:38
【问题描述】:

我有以下代码……

for i=1:100
   for j=1:200

       for k=1:100

             error = DOprocess(i,j,k);

             if(error==const)
               %%Break all loops...
             end
       end

  end
end

现在的问题是 DoProcess 函数每次运行都需要大量时间。但我想找到错误代码等于 const 的 I,j,k 的组合。我也不知道 DoProcess 的内部逻辑。我知道,如果我知道我可以使用优化技术来找到最佳解决方案。对于 I、j 和 k 的多个组合,DoProcess 也可以返回一个等于 const 的错误。我只需要找到第一次出现。所以任何人都可以建议我替代搜索算法而不是这些循环。该代码在 Matlab 中,但对于 c/c++ 人来说,您只需将 end 替换为} 并在每个 for 循环的开头保留一个 {。如果需要,我已准备好在 matlab 中实现搜索算法。

【问题讨论】:

  • 购买 100*100*200 处理器并并行执行。
  • 根据您提供的信息,我怀疑是否会有更好的方法来完成此任务。在最坏的情况下,您可能需要查看所有可能的组合。
  • 这个DoProcess 返回的错误代码是否有任何系统(例如,对于较大的 i 或 j 或 k 值,只有升序错误编号?)?因为(我知道)加快搜索 算法 本身的唯一方法是,如果您至少可以预测返回值的趋势。如果DoProcess 返回的内容完全是随机的,那么除了暴力破解所有组合之外,不可能找到它——只有更快(和/或并行)的硬件才能让它更快——使用更多内核的简单解决方案可能是OpenMP
  • 我建议你深入 DoProcess 函数查看更多细节。
  • 假设DOprocess(i,j,k) 是一个连续函数,您可以将成本函数定义为(const - DOprocess(i,j,k))^2 并尝试像fmincon 这样的简单优化算法,例如找到最优i,@987654329 @ 和 k。如果不是,那么您将不得不像其他人所说的那样暴力破解它。但我认为它很有可能具有合理的行为,因此可以进行优化。

标签: c++ algorithm matlab


【解决方案1】:

如果没有 DoProcess 函数的任何额外信息, 如果 (i, j, k) 结果不是一直在变化,实践中可能的两种优化方法:

  1. 离线执行此操作,并缓存预期的 (i, j, k) 组合
  2. 或者,在在线环境中执行一次,然后缓存。避免重复计算。

【讨论】:

    【解决方案2】:

    您可以将它们组合为以下示例:

        max = 100*200*100;
        for (n = 0:max) {
            temp = n;
            i = temp % 100+1;
            temp/=100;
            j = temp % 200+1;
            temp/=200;
            k = temp % 100+1;
    
            error = DOprocess(i,j,k);
    
            if(error==const)
                break;
            end
        }
    

    【讨论】:

    • 我认为这不会导致加速,而是相反,所有这些模和除运算......
    • 它不会加速,但是如果有任何代码重构它可以避免许多嵌套的for循环并且更好地管理。
    • hm,那个代码看起来不是更简单,而是更复杂,我看不出它会如何简化重构
    • 这种for循环的转换只有在你想并行化时才有用。如果你用 parfor 替换这个单曲,它可能会更快。由于开销增加,也可能比替换原始代码中的单个循环慢。
    【解决方案3】:

    这不是算法优化,但您可以并行执行此代码(假设迭代之间没有依赖关系(DOprocess)。

    【讨论】:

      【解决方案4】:

      由于不了解DoProcess函数的细节,无法进一步优化代码。

      如果您以某种方式获得了函数的实现,则可以展开至少一个循环,并使用 SIMD 函数(几乎每个处理器都至少部分支持)。

      如果你只是想让你的计算更快地完成,那么你可以尝试添加更多线程,看看是否有帮助。

      【讨论】:

        【解决方案5】:

        提高速度的一种可能性是在 DOprocess 中进行矢量化,并至少为一个输入接受一个矢量。

        http://www.mathworks.de/de/help/matlab/matlab_prog/vectorization.html

        这样的向量化代码更快,因为循环的开销被移除或每个向量仅存在一次。此外,许多基本操作对于大型数据集非常有效,并且使用多线程进行计算。这不需要并行工具箱。

        【讨论】:

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