优化相关矩阵的计算

时间:2012-02-27 00:53:32

标签: c performance numerical

下面的代码在给定协方差矩阵的情况下计算相关矩阵。我怎么能写得更好?问题是这部分代码将在尺寸大约为100 x 100的矩阵上运行1000次。

// Copy upper triangle of covariance matrix to correlation matrix
for(i = 0; i < rows; i++){
  for(j = i; j < rows; j++){
    corrmatrix.array[i * rows + j] = covmatrix.array[i * rows + j];
  }
}

// Calculate upper triangle of corr matrix
for(i = 0; i < rows; i++){

  root = sqrt(covmatrix.array[(i * rows) + i]);    

  for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] /= root;
  }

  k = i * rows;

  for(j = i; j < rows; j++){ // Move across
    corrmatrix.array[ k + j ] /= root;
  }

}

// Copy upper triangle to lower triangle
for(i = 0; i < rows; i++){
  k = i * rows;
  for(j = i; j < rows; j++){
    corrmatrix.array[ (j * rows) + i ] = corrmatrix.array[ k + j ];
  }
}

我已经检查过行和列是否相等等,所以我只是在各处使用行。我想优化速度(显着)。

PS:

  1. 矩阵以行主密集格式存储
  2. 我现在不使用打包存储。
  3. 谢谢

1 个答案:

答案 0 :(得分:1)

对我跳出的第一件事就是你在内循环中用相同的数字进行除法。

不要这样做。分工很慢。

你应该做的是乘以root的倒数而不是重复除以:

inv_root = 1. / sqrt(covmatrix.array[(i * rows) + i]);

for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] *= inv_root;
}

k = i * rows;

for(j = i; j < rows; j++){ // Move across
    corrmatrix.array[ k + j ] *= inv_root;
}

虽然这种优化对编译器来说似乎很明显,但由于浮点严格性,可能不允许进行此优化。您可以尝试使用-ffast-math(在GCC中)或类似的东西来放宽浮点设置。