當程式訪問多個陣列時,經常會出現有些陣列按行訪問,有些陣列按列訪問的情況。以矩陣的乘法為例, c=a
×bc=a\times b
c=a×
b ,經典的計算矩陣乘法的演算法如下:
void mult() {
for(int i=0;i 可以看出,內部的兩個迴圈 j
jj , k
kk, 將反覆讀取矩陣 mat
rix_
b[n]
[n]matrix\_b[n][n]
matrix
_b[n
][n]
的全部的 n×n
n\times n
n×n 個元素,以及反覆讀取矩陣 mat
rix_
a[n]
[n]matrix\_a[n][n]
matrix
_a[n
][n]
的全部的第 i
ii 行的 n
nn 個元素,所產生的結果 res
resre
s 將存入至結果矩陣 mat
rix_
c[n]
[n]matrix\_c[n][n]
matrix
_c[n
][n]
的第 i
ii 行。
考慮此時cache的失效情況,拋開cache大小無限制或者cache的大小完全能裝下這三個陣列的最為理想的情況。考慮對三個陣列訪問時,導致cache失效的情況,最壞的情況是,每次的訪問都失效,這是會導致共 2n3
+n22n^3 + n^2
2n3+n2
次的失效。為了減少失效,下面有兩種方法能顯著的減小cache的失效率。
void mult() {
int i,j,k;
for(i=0;i毫無疑問的是,轉置矩陣也是乙個耗時的過程,但在轉置處花費的時間和後面計算矩陣的乘積結果所節省的時間達到了很好的折中,下面是測試圖:
(矩陣規模是 1025
×1025
1025\times 1025
1025×1
025,生成矩陣的方法是生成隨機的double型別的浮點數 )
可以看到,轉置操作再加上轉置後的矩陣乘的開銷遠遠小於直接矩陣乘的開銷。
其中最主要的原因就是,轉置後的矩陣乘法,最內部的迴圈 k
kk ,都將反覆讀取矩陣 mat
rix_
a[n]
[n]matrix\_a[n][n]
matrix
_a[n
][n]
的全部的第 i
ii 行的 n
nn 個元素,以及矩陣 mat
rix_
b[n]
[n]matrix\_b[n][n]
matrix
_b[n
][n]
的全部的第 j
jj 行的 n
nn 個元素,而這樣的讀取方式,很好地利用了空間區域性性,讓對於程式設計師透明的cache發揮了重要的作用。
分塊是一種經典的利用cache來提公升程式效能的技術。分塊演算法不是對陣列的整行或者整列進行訪問的,而是把對大陣列的訪問分解成對子矩陣的訪問。
為了保證正在訪問的元素能在cache中命中,把原程式內部改為僅僅對大小為 b×b
b\times b
b×b 的子陣列進行計算,其中 b
bb 稱為分塊因子,**如下:
void multb() {
int jj,kk,i,j,k;
double r;
for(jj=0;jj 這時再以開始的條件考慮失效次數,可以初步判斷cache的失效率會降低,測試結果如下:
**如下:
void mult_t_and_b() {
int jj,kk,i,j,k;
double r;
for(i=0;i測試時間如下:
程式的平均訪存公式如下:
平 均訪
存時間=
命中時間
+失效率
×失效開
銷平均訪存時間=命中時間+失效率\times 失效開銷
平均訪存時間
=命中時
間+失效
率×失效
開銷
07 降低cache不命中率
目錄 8種降低cache不命中率的方法 增加cache大小 增加cache容量 提高相連度 偽相連cache 硬體預取 編譯器控制的預取 編譯優化 犧牲 cache 三種型別的不命中 分類 強制性不命中 容量不命中 衝突不命中 三種不命中所佔的比例 減少三種不命中的方法 對於給定的cache容量,當...
nginx nginx快取cache的幾種方式
nginx快取cache的幾種方式 官方詳細引數 1 傳統快取之一 404 這個辦法是把nginx的404錯誤定向到後端,然後用proxy store把後端返回的頁面儲存。location location fetch 使用的時候還有要注意是nginx要有許可權往 home tmp和 home ht...
通過降低CPU頻率 達到降低功耗的目的
最近用一台老機子h61 i5 2320 p106 100 作為ai伺服器 系統用的是centos 7。系統對cpu的依賴度不大,能正常開機 集顯能正常輸出就好,主要是依靠 礦卡進行ai計算。然而由於 i5 2320的 tdp 高達95w 開機實測整機待機功耗接近90w cpu gpu 非常的不節能 ...