2012-02-27 98 views
1

下面的代码计算给定协方差矩阵的相关矩阵。我怎样才能写得更好?问题是这部分代码将在矩阵,其尺寸为约100×100优化相关矩阵的计算

// 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 ]; 
    } 
} 

我做检查的行和列是相等的等运行时间1000,所以我只是用行随处可见。我想优化速度(显着)。

PS:

  1. 矩阵存储在行优先,
  2. 我不使用填充存储现在密集的格式。

谢谢

回答

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中)或类似的东西来放宽您的浮点设置。

+0

谢谢,我会补充一点。我能做出更多优化吗? – mod0 2012-02-27 01:10:51

+0

没有那么容易。根据您的编译器,它可能能够为您进行矢量化。除此之外,代码可能会受到您所做的大量内存访问的限制。解决这个问题的唯一方法就是重构算法 - 这可能也可能不容易。 – Mysticial 2012-02-27 01:12:57

+0

好的。谢谢。 – mod0 2012-02-27 01:23:26