多核下寫高性能并行程序
什么樣的程序執(zhí)行效率高?
程序的數(shù)據(jù)和指令都在cache中,沒有cache miss出現(xiàn)。
所以如何讓并行程序性能高基本可以演變成 如何減少cache miss?
尤其是多核下,并行程序cache的問題已經(jīng)無法回避了,否則并行的效率還沒有一個線程高。
寫程序的時候MESI協(xié)議要時刻浮現(xiàn)在眼前。
借用一句歌詞:現(xiàn)在不是從前了,兔子比狐貍狡猾了。
1.絞盡所有的腦汁,避免使用全局變量,尤其是程序運行過程中可能修改的變量。所有線程只讀的變量可以放松一丁點兒要求。
2.per thread per core。每個core運行一個線程,每個線程運行在一個cpu core上。
3.Keep data structures ?per core。每個core僅僅修改自己的數(shù)據(jù)結構。
4.Keep data structures cache alignment。保證結構體定義的時候cache line對齊??梢宰约禾砑觩ad,也可以用gcc提供的__attribute__。
5.避免false sharing。定義數(shù)據(jù)結構的時候不能這么搞: int num[CPU_NUMS],這樣在for循環(huán)中對num[i]++的時候就會造成false sharing。這也是為什么結構體定義要cache line對齊。
6. Lock-free data structures。鎖的代價是巨大的,搞不好還會死鎖,多核間通信用lock-free fifo。
7.cpu affinity。線程創(chuàng)建后立即綁定到具體的core上,然后再 進行分配內(nèi)存,保證內(nèi)存分配在自己的領土這邊。
8.分支預測。使用gcc提供的likely和unlikely。
9.公共子表達式消除。一個函數(shù)中如果多次用到同一個表達式,可以開始的時候定義一個指針。
10.循環(huán)中消除指針引用。比如下面這樣:
for(i=0; i< 1000; i++)
{
? ? *dest++;
}
可以先定義一個局部變量進行累加,最后再把局部變量賦值給指針。
11.X86平臺intel提供了很多的sse指令,尤其是在字符串的搜索和查找方面。
12.多用perf tool。
暫時想到的先記錄下來,找個時間給出具體的代碼逐條舉例說明一下。