在 multicore 的 CPU 電腦中,為了在多核心的狀況下,讓程式跑得更快,會把資料放在 cache 中,在 cache system 裡面儲存的記憶體的基本單位稱為 cache lines,通常 cache line 都是 2 的指數次方,也就是 32 ~ 256 bytes,最常見的 cache line size 為 64 bytes。
false sharing 發生在多核心執行不同的 threads 時,不同的thread修改到存在同一個 cache line 裡面不同的變數,因為頻繁地發生 cache invalidate,因此造成在多核心的狀況下,反而削弱了程式的效能。
為了避免這個問題,解決方式就是不要讓兩個以上的 threads 寫入同一個變數,或是 cache line。
這個圖片說明了 false sharing 發生的狀況,core 1 想要更新 X,core 2 想要更新 Y,但 X 與 Y 存放在同一個 cache line 中,每一個 thread 都需要競爭 cache line 的使用權,去更新變數的內容,當 core 1 取得 cache line 使用權,就會造成 core 2 的 cache invalidated,多次來來回回之後,影響了效能。
提供了一個 java 的範例,文章中刻意製造了多個 threads,並實際計算在 multicore 的狀況下,耗費的時間,使用了連續七個沒有使用到的 long 變數,利用這個方法來避免讓多個 VolatileLong 放在同一個 cache line 裡面。
What is @Contended and False Sharing ?
The end for false sharing in Java?
Java 8 根據上面的方式,提供了一個新的 annotation @Contended,他可以用在兩個連續的變數之間,經過 compiler 自動加上 padding variables,用以避免這兩個變數被配置在同一個 cache line。
References
https://en.wikipedia.org/wiki/False_sharing
沒有留言:
張貼留言