1. 程式人生 > >【併發】偽共享 —— False Sharing

【併發】偽共享 —— False Sharing

轉自: http://ifeve.com/falsesharing/

作者:Martin Thompson  譯者:丁一

快取系統中是以快取行(cache line)為單位儲存的。快取行是2的整數冪個連續位元組,一般為32-256個位元組。最常見的快取行大小是64個位元組。當多執行緒修改互相獨立的變數時,如果這些變數共享同一個快取行,就會無意中影響彼此的效能,這就是偽共享。快取行上的寫競爭是執行在SMP系統中並行執行緒實現可伸縮性最重要的限制因素。有人將偽共享描述成無聲的效能殺手,因為從程式碼中很難看清楚是否會出現偽共享。

為了讓可伸縮性與執行緒數呈線性關係,就必須確保不會有兩個執行緒往同一個變數或快取行中寫。兩個執行緒寫同一個變數可以在程式碼中發現。為了確定互相獨立的變數是否共享了同一個快取行,就需要了解記憶體佈局,或找個工具告訴我們。Intel VTune就是這樣一個分析工具。本文中我將解釋Java物件的記憶體佈局以及我們該如何填充快取行以避免偽共享。

cache-line.png
圖 1.

圖1說明了偽共享的問題。在核心1上執行的執行緒想更新變數X,同時核心2上的執行緒想要更新變數Y。不幸的是,這兩個變數在同一個快取行中。每個執行緒都要去競爭快取行的所有權來更新變數。如果核心1獲得了所有權,快取子系統將會使核心2中對應的快取行失效。當核心2獲得了所有權然後執行更新操作,核心1就要使自己對應的快取行失效。這會來來回回的經過L3快取,大大影響了效能。如果互相競爭的核心位於不同的插槽,就要額外橫跨插槽連線,問題可能更加嚴重。

對於HotSpot JVM,所有物件都有兩個字長的物件頭。第一個字是由24位雜湊碼和8位標誌位(如鎖的狀態或作為鎖物件)組成的Mark Word。第二個字是物件所屬類的引用。如果是陣列物件還需要一個額外的字來儲存陣列的長度。每個物件的起始地址都對齊於8位元組以提高效能。因此當封裝物件的時候為了高效率,物件欄位宣告的順序會被重排序成下列基於位元組大小的順序:

  1. doubles (8) 和 longs (8)
  2. ints (4) 和 floats (4)
  3. shorts (2) 和 chars (2)
  4. booleans (1) 和 bytes (1)
  5. references (4/8)
  6. <子類欄位重複上述順序>

為了展示其效能影響,我們啟動幾個執行緒,每個都更新它自己獨立的計數器。計數器是volatile long型別的,所以其它執行緒能看到它們的進展。

01 public final class FalseSharing
02 implements Runnable
03 {
04 public final static int NUM_THREADS = 4// change
05 public final static long ITERATIONS = 500L * 1000L * 1000L;
06 private final int arrayIndex;
07
08 private static VolatileLong[] longs = new VolatileLong[NUM_THREADS];
09 static
10 {
11 for (int i = 

相關推薦

併發共享 —— False Sharing

轉自: http://ifeve.com/falsesharing/ 作者:Martin Thompson  譯者:丁一 快取系統中是以快取行(cache line)為單位儲存的。快取行是2的整數冪個連續位元組,一般為32-256個位元組。最常見的快取

共享(False Sharing)

作者:Martin Thompson  譯者:丁一 快取系統中是以快取行(cache line)為單位儲存的。快取行是2的整數冪個連續位元組,一般為32-256個位元組。最常見的快取行大小是64個位元組。當多執行緒修改互相獨立的變數時,如果這些變數共享同一個快取行,就會無意中影響彼此的效能

從Java視角理解共享(False Sharing)

從Java視角理解系統結構連載, 關注我的微博([url="http://weibo.com/coderplay"]連結[/url])瞭解最新動態從我的[url="http://coderplay.iteye.com/blog/1485760"]前一篇博文[/url]中, 我

從快取行出發理解volatile變數、共享False sharing、disruptor

volatile關鍵字 當變數被某個執行緒A修改值之後,其它執行緒比如B若讀取此變數的話,立刻可以看到原來執行緒A修改後的值 注:普通變數與volatile變數的區別是volatile的特殊規則保證了新值能立即同步到主記憶體,以及每次使用前可以立即從記憶體重新整理,

Java中的共享(false sharing)以及應對方案

1. 什麼是偽共享 CPU快取系統中是以快取行(cache line)為單位儲存的。目前主流的CPU Cache的Cache Line大小都是64Bytes。在多執行緒情況下,如果需要修改“共享同一個快取行的變數”,就會無意中影響彼此的效能,這就是偽共享(Fa

併發併發程式設計的挑戰

1. 上下文切換 a. 概念: i. CPU通過時間片分配演算法來迴圈執行任務,當前任務執行一個時間片後會切換到下一個任務。但是,在切換前會儲存上一個任務的狀態,以便下次切換回這個任務時,可以再載入這個任務的狀態。所以任務從儲存到再載入的過程就是一次上下文切換 b. 舉

併發神祕的java併發包

  java併發包 一 同步控制工具  重量級鎖 Synchronized 類鎖,物件鎖,變數鎖 1.1.1 類鎖   就是對整個靜態的class檔案加鎖,也就是說一個地方用到了這個class檔案,其他地

併發Amdahl's Law 阿姆達爾定律

轉自:http://book.2cto.com/201301/12892.html 利用Amdahl定律,可以計算出通過改進計算機某一部分而能獲得的效能增益。Amdahl定律表明,使用某種快速執行模式獲得的效能改進受限於可使用此種快速執行方式的時間比例。 Amdah

shell中的多程序併發

根據我個人的理解, 所謂的多程序 只不過是將多個任務放到後臺執行而已,很多人都用到過,所以現在講的主要是控制,而不是實現。先看一個小shell:看執行結果: 很明顯是8s=============================這種不佔處理器卻有很耗時的程序,我們可以通過一

併發多執行緒程式設計中條件變數和虛假喚醒的討論

轉自:http://blog.csdn.net/puncha/article/details/8493862 From: http://siwind.iteye.com/blog/1469216 From:http://en.wikipedia.org/wiki/S

併發ConcurrentHashMap原理分析

集合是程式設計中最常用的資料結構。而談到併發,幾乎總是離不開集合這類高階資料結構的支援。比如兩個執行緒需要同時訪問一箇中間臨界區(Queue),比如常會用快取作為外部檔案的副本(HashMap)。這篇文章主要分析jdk1.5的3種併發集合型別(concurrent,cop

IPCPosix共享記憶體區與mmap記憶體對映

共享記憶體是一種IPC形式,與其它IPC機制如管道、訊息佇列等相比,資料不必在程序與核心間多次交換,程序間通訊的速度更快。當共享記憶體區對映到共享它的程序的地址空間時,再加以一些同步控制,這些程序就可以進行資料傳送了。mmap函式提供了記憶體對映功能,可以把一個

一段程式碼,兩倍時差,直擊併發程式設計共享

## 一、前言 【閒話開篇】:這段時間專案接近尾聲,我終於閒了一點,又拿起了早先未看完的書《JAVA高併發程式設計》,強迫自己學習。看到其中介紹《無鎖的快取框架:Disruptor》時,接觸到了一個概念——偽共享(false sharing),說是會影響併發程式的執行效能,被很多人描述成無聲的效能殺手,突然

百度開源分散式id生成器uid-generator原始碼剖析 共享false sharing),併發程式設計無聲的效能殺手 一個Java物件到底佔用多大記憶體? 寫Java也得了解CPU--共享

百度uid-generator原始碼 https://github.com/baidu/uid-generator   snowflake演算法 uid-generator是基於Twitter開源的snowflake演算法實現的。 snowflake將long的64位分為了3部分,時間戳、

百度uid-generator原始碼 共享false sharing),併發程式設計無聲的效能殺手 一個Java物件到底佔用多大記憶體? 寫Java也得了解CPU--共享

https://github.com/baidu/uid-generator   snowflake演算法 uid-generator是基於Twitter開源的snowflake演算法實現的。 snowflake將long的64位分為了3部分,時間戳、工作機器id和序列號,位數分配如下。

共享False Sharing

目錄 一、計算機的基本結構 二、快取行 三、偽共享 四、如何避免偽共享 快取系統中是以快取行(cache line)為單位儲存的,當多執行緒修改互相獨立的變數時,如果這些變數共享同一個快取行,就會無意中影響彼此的效能,這就是偽共享。 一、計算機的基本結構 下圖是計算的

java併發多個執行緒間共享資料

先看一個多執行緒間共享資料的問題: 設計四個執行緒,其中兩個執行緒每次對data增加1,另外兩個執行緒每次對data減少1。   從問題來看,很明顯涉及到了執行緒間通資料的共享,四個執行

雜談 什麽是共享false sharing)?

完全 分享圖片 throws 其它 也有 ava 循環 哪些 訪問 問題 (1)什麽是 CPU 緩存行? (2)什麽是內存屏障? (3)什麽是偽共享? (4)如何避免偽共享? CPU緩存架構 CPU 是計算機的心臟,所有運算和程序最終都要由它來執行。 主內存(RAM)是數據

雜談 什麼是共享false sharing)?

問題 (1)什麼是 CPU 快取行? (2)什麼是記憶體屏障? (3)什麼是偽共享? (4)如何避免偽共享? CPU快取架構 CPU 是計算機的心臟,所有運算和程式最終都要由它來執行。 主記憶體(RAM)是資料存放的地方,CPU 和主記憶體之間有好幾級快取,因為即使直接訪問主記憶體也是非常慢的。 如果對一塊資

翻譯自mos文章即使resource_limit = false, password的 資源限制也會生效

作用 pro use def alt doc 資源限制 lock bsp 即使resource_limit = false, password的 資源限制也會生效 參考原文: Resource limits for passwords work even with re