以矩陣乘法為例 瞭解cpu cache對程式效能的影響
阿新 • • 發佈:2019-01-02
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/*square1.cpp*//*未經優化的矩陣乘法程式*/#include <iostream>using namespace std;#define N 1000int a[N][N] = {0}, b[N][N] = {0}, c[N][N] = {0};int main() { int i, j, k; for (i = 0; i < N; i++) { for (j = 0; j < |
1 2 3 4 5 6 |
/*square2.cpp*/ /*優化過的矩陣乘法程式*/ #include <iostream> using namespace std; #define N 1000 int a[N][N] = {0}, b[N][N] = {0}, c[N][N] = {0}; int main() { int i, j, k; for (i = 0; i < N; i++) { for (j = 0; j < N; |
square1.cpp中因為第三層迴圈(最內層迴圈)是對k進行迴圈,因此b[k][j]是對b逐列進行訪問。我們知道記憶體中二維陣列是以行為單位連續儲存的,逐列訪問將會每次跳1000*4(bytes)。根據cpu cache的替換策略,將會有大量的cache失效。
因此square2.cpp將j迴圈和k迴圈交換位置,這樣就保證了
c[i][j] += a[i][k] * b[k][j];
這條語句對記憶體的訪問是連續的,增加了cache的命中率,大大提升了程式執行速度。
我們來看一下實測效果:(測試環境:64位雙核2.4GHz cpu)
執行時間測試:
時間居然會相差近10倍。 可見利用好cpu cache優化我們的程式,是非常有必要掌握的技能。
平時寫程式時,也應當儘量使cpu對記憶體的訪問,是儘可能連續的