簡體   English   中英

二維矢量優化

[英]2D Vector Optimization

這只是一個緊湊的測試用例,但是我有一個double的向量,並且我想填充所有成對差異的方陣(2D向量)。 使用-O3優化進行編譯時,這在我的計算機上大約需要1.96秒(僅從嵌套的double for循環計算)。

#include <vector>
using namespace std;

int main(){
  vector<double> a;
  vector<vector<double> > b;
  unsigned int i, j;
  unsigned int n;
  double d;

  n=10000; //In practice, this value is MUCH bigger
  a.resize(n);

  for (i=0; i< n; i++){
    a[i]=static_cast<double>(i);
  }

  b.resize(n);
  for (i=0; i< n; i++){
    b[i].resize(n);
    b[i][i]=0.0; //Zero diagonal
  }

  for (i=0; i< n; i++){
    for (j=i+1; j< n; j++){
      d=a[i]-a[j];

      //Commenting out the next two lines makes the code significantly faster
      b[i][j]=d; 
      b[j][i]=d;
    }
  }
  return 0;
}

但是,當我注釋掉這兩行時:

b[i][j]=d; 
b[j][i]=d;

該程序將在大約0.000003秒內完成(僅從嵌套的double for循環計算)! 我真的沒想到這兩行是限速步驟。 我盯着這段代碼已經有一段時間了,我沒有想法。 任何人都可以就如何優化此簡單代碼段提供任何建議,以便可以大大減少時間嗎?

當您注釋掉這兩行時,嵌套循環中剩下的就是繼續計算d ,然后丟棄結果。 由於這對程序的行為沒有任何影響,因此編譯器將優化嵌套循環。 這就是程序幾乎立即完成的原因。

實際上,我使用g++ -O3兩次編譯了代碼,一次在嵌套循環中僅使用d=a[i]-a[j]語句,一次將嵌套循環完全刪除,從而證實了這一點。 發出的代碼是相同的。

但是,由於缺少高速緩存,因此您的代碼當前比必須的慢。 當您像這樣在嵌套循環中訪問二維數組時,應盡可能安排迭代在內存中連續進行。 這意味着第二個索引應該是變化更快的索引。 b[j][i]的訪問違反了此規則,並且缺少緩存。 因此,讓我們重寫。

之前:

for (i=0; i< n; i++){
    for (j=i+1; j< n; j++){
        d=a[i]-a[j];
        b[i][j]=d; 
        b[j][i]=d;
    }
}

定時:

real    0m1.026s
user    0m0.824s
sys     0m0.196s

后:

for (i = 0; i < n; i++) {
    for (j = 0; j < i; j++) {
        b[i][j] = a[j] - a[i];
    }
    for (j = i+1; j < n; j++) {
        b[i][j] = a[i] - a[j];
    }
}

定時:

real    0m0.335s
user    0m0.164s
sys     0m0.164s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM