1 . 優化目標
對於密集型應用提高cpu處理速度。核心提升緩存利用
2. 理解cpu架構
L3 +內存是共享,L2+L1(分開數據與指令)cpu獨享
大約時鐘週期 | |
L1 | 4 |
L2 | 12 |
L3 | 30 |
內存 | 100 |
我的電腦3.3ghz ,1個時鐘週期大約0.33納秒。如果cpu操作的數據或指令都在緩存中則直接讀取,會帶來倍極大的性能提升。所以對於cpu性能的提升核心 是提升cpu緩存的命中率。
3. Cache line
空間局部性原理:通常使用了a,隔壁的b,c,c都較大概率使用。所以cpu緩存一次載入abcd。。。等後續的元素。 通常Cacle line 64k 可配置coherency_line_size。加載a,後續的元素補足。這是爲什麼順序讀取會較快。同理,int 比float 少一倍字節,理論速度也是比float快很多。 Cache line 的特性有很多應用, 比如nginx hash表存放域名。 桶大小就是cache line的大小。Disruptor 是爲了最求cpu性能極致的一個併發框架,前後加7個long ,jdk 8 也有專門的註解@sun.misc.Contended+-XX:-RestrictContended,jdk9廢棄
public class Data{
public long p1,p2,p3,p4,p5,p6,p7;//防止與前一個對象產生僞共享
public long X;
public long p1,p2,p3,p4,p5,p6,p7;//防止不相關變量僞共享;
public long Y;
public long p1,p2,p3,p4,p5,p6,p7;//防止與下一個對象產生僞共享
}
4.提升指令緩存命中率
cpu含有分支預測器。借用別人例子:
int array[N];for (i = 0; i < TESTN; i++) array[i] = rand() % 256;
//寫法1
for(i = 0; i < N; i++) { if (array [i] < 128) array[i] = 0;}
sort(array, array +N);
//寫法2
sort(array, array +N);
for(i = 0; i < N; i++) { if (array [i] < 128) array[i] = 0;}
先排序會快很多。原因操作指令緩存,cpu含有分支預測提高速度。
5.多線程情況下的緩存應用
多線程情況下,線程調度會將緩存失效,解決辦法線程或進程綁定cpu。減少cpu 核心遷移的次數。