【问题标题】:optimize repetitive coefficients evaluation优化重复系数评估
【发布时间】:2012-02-22 12:37:54
【问题描述】:

我正在求解 3 个不同的线性方程系统,其中每个系统都取决于前一个系统的结果。它们都共享一些系数,然后与之前的结果一起定义新系统(当然第一个由它自己定义的除外)。

代码有点像这样:

vector<double>point(n);//initialized to values
vector<double>A(n*n,0);
vector<double>b(n,0);
double coefficient;

for(int i=0;i<n;i++){
  for(int j=0;j<n;j++){
  coefficient=myCoeff(point[i],point[j]);
    //A[i+j*n] and b[j] initialized using coefficient
  }
}

vector<double>x(n) //initialized as solution of A\b

for(int i=0;i<n;i++){
  for(int j=0;j<n;j++){
  coefficient=myCoeff(point[i],point[j]);
    //A[i+j*n] and b[j] initialized using coefficient and x
  }
}
//x=A\b
//and so on for the third system

分析代码显示 80% 的时间用于调用 myCoeff。优化 myCoeff 超出了我的兴趣。

我有两个选择: -将系数写入文件一次并读取两次 - 使用 parallel_for 而不是外部 for 循环。

是否可以将这两个选项结合起来? 欢迎任何其他建议,如果您需要有关我可以提供的代码的更多详细信息。

【问题讨论】:

    标签: c++ optimization parallel-processing


    【解决方案1】:

    使用 parallel_for 并行化循环(外部循环或两者)看起来是个好主意,因为对 myCoeff 的调用似乎很昂贵。

    但是,将所有系数写入文件系统可能不是一个好主意,因为文件系统 I/O 往往非常昂贵并且会中断程序的执行流程。如果您可以支付额外的 n*n 存储空间,则将系数存储在内存中可能会更好:

    vector<double> coeff(n*n, 0);
    for (i...) {
      for (j...) {
        coeff[j+n*i] = myCoeff(point[i],point[j]);
      }
    }
    

    这可以很容易地与循环并行化结合起来。

    如果您坚持在文件系统中存储系数的想法(也许是为了减少内存使用),那么仅使用一个文件会使并行化变得非常困难(文件是按顺序访问的)。相反,您可能希望在矩阵中的每行创建一个文件。这样,您可以轻松地将系数存储与外部循环的并行化结合起来。

    此外,您最好按行存储矩阵系数:A[i*n+j] 或反转 i 和 j 循环。

    【讨论】:

    • 我实际上正在考虑这种方法。系数实际上是 4,所以这将使 5*n*n 和最大 n 大约是现在的 0.4-0.5,但可能就足够了。关于 A 的索引,您是对的,我一开始是这样做的,在随后的更正过程中,事情变得一团糟。
    • @MarcoS 如果您有多个系数并将它们存储在内存中,请确保将与同一 (i,j) 对相关的所有 4 个系数组合在一起(例如将它们分组到结构中并存储一个向量),而不是每个系数都有一个 n*n 矩阵。
    • 也许你也知道这一点,myCoeff 来自一个 dll。 parallel_for 可以吗?如果需要,我可以编译 myCoeff。
    • @MarcoS myCoeff 可以驻留在 dll 中。 myCoeff 的唯一要求是它必须是线程安全的。
    猜你喜欢
    • 2019-06-27
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 2016-11-05
    • 2017-06-26
    • 2020-10-14
    相关资源
    最近更新 更多