1. 程式人生 > >cpu偽共享問題

cpu偽共享問題

          CPU內部也會有自己的快取,內部的快取單位是行,叫做快取行。在多核環境下會出現CPU之間的記憶體同步問題(比如一個核載入了一份快取,另外一個核也要用到同一份資料),如果每個核每次需要時都往記憶體中存取,這會帶來比較大的效能損耗,這個問題一般是通過MESI協議來解決的。

          MESI協議中包含M、E、S、I四個狀態,分別的意思是:

  • M(修改, Modified): 本地處理器已經修改快取行, 即是髒行, 它的內容與記憶體中的內容不一樣. 並且此cache只有本地一個拷貝(專有).
  • E(專有, Exclusive): 快取行內容和記憶體中的一樣, 而且其它處理器都沒有這行資料
  • S(共享, Shared): 快取行內容和記憶體中的一樣, 有可能其它處理器也存在此快取行的拷貝
  • I(無效, Invalid): 快取行失效, 不能使用
                    cpu在對快取行進行了不同的操作後,在cpu快取行中會記錄快取的不同狀態。當一個核要對共享的資料進行寫操作時,需要給其他核發送RFO(REQUEST FOR OWNER)訊息並把其他核的資料改成I態。這是一種比較消耗效能的操作。           cpu的偽共享問題本質是:幾個在邏輯上並不包含在同一個記憶體單元內的資料,由於被cpu載入在同一個快取行當中,當在多執行緒環境下,被不同的cpu執行,導致快取行失效而引起的大量的快取命中率降低。           例如:當兩個執行緒分別對一個數組中的兩份資料進行寫操作,每個執行緒操作不同index上的資料,看上去,兩份資料之間是不存在同步問題的,但是,由於他們可能在同一個cpu快取行當中,這就會使這一份快取行出現大量的快取失效,如前所述當一份執行緒更新時要給另一份執行緒傳送RFO訊息並把它的快取失效掉。           解決這個問題的一個辦法是讓這個陣列中不同index的資料在不同的快取行:因為快取行的大小是64個位元組,那我們只要讓陣列中沒份資料的大小大於64個位元組,就可以保證他們在不同的快取行當中,就能避免這樣的偽共享問題。           比如一個類當中原本只有一個long型別的屬性。這樣這個型別的物件只佔了16個位元組(java物件頭有8位元組),如果這個型別被定義成一個長度為4的陣列,這個陣列的所有資料都可能在一個快取行當中,就可能出現偽共享問題,那麼這個時候,就可以採用補齊(padding)的辦法,在這個型別中加上public long a,b,c,d,e,f,g;這六個無用的屬性定義,使得這個型別的一個例項佔用記憶體達到64位元組,這樣這個型別的偽共享問題就得到了解決,在多執行緒當中對這個型別的陣列進行寫操作就能避免偽共享問題。

相關推薦

百度開源分散式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和序列號,位數分配如下。

cpu共享問題

          CPU內部也會有自己的快取,內部的快取單位是行,叫做快取行。在多核環境下會出現CPU之間的記憶體同步問題(比如一個核載入了一份快取,另外一個核也要用到同一份資料),如果每個核每次需要時都往記憶體中存取,這會帶來比較大的效能損耗,這個問題一般是通過MESI

轉載-cpu共享問題

 CPU內部也會有自己的快取,內部的快取單位是行,叫做快取行。在多核環境下會出現CPU之間的記憶體同步問題(比如一個核載入了一份快取,另外一個核也要用到同一份資料),如果每個核每次需要時都往記憶體中存取,這會帶來比較大的效能損耗,這個問題一般是通過MESI協議來解決的。

快取行、cpu共享和快取行填充

由於在看disruptor時瞭解到快取行,以及快取行填充的問題,所以各處瞭解記在這裡 一、快取行 CPU 為了更快的執行程式碼。於是當從記憶體中讀取資料時,並不是只讀自己想要的部分。而是讀取足夠的位元組來填入快取記憶體行。根據不同的 CPU ,快取記憶體

共享、快取行填充以及CPU快取機制

關於偽共享的一篇好文,轉載自: 1.認識CPU Cache CPU Cache概述 隨著CPU的頻率不斷提升,而記憶體的訪問速度卻沒有質的突破,為了彌補訪問記憶體的速度慢,充分發揮CPU的計算資源,提高CPU整體吞吐量,在CPU與記憶體之間引入了一級Cach

對於CPU記憶體共享問題學習

事情由來是對於Log4j2中存在兩種非同步處理日誌的方式,AsyncAppender和AsyncLogger兩種,一個是基於BlockingQueue實現,一個是基於Disruptor實現的。。 而Disruptor是無鎖的方式,環形佇列,對於隊首尾都是採用資料paddin

CPU Cache的優化:解決共享問題

無鎖的快取框架: Disruptor 除了使用CAS和提供了各種不同的等待策略來提高系統的吞吐量外。Disruptor大有將優化進行到底的氣勢,它甚至嘗試解決CPU快取的偽共享問題。什麼是偽共享問題呢?我們知道,為了提高CPU的速度,CPU有一個快取記憶體Cac

cpu快取共享

/** * @描述 * @引數 $ * @返回值 $ * @建立人 [email protected] * @建立時間 $ * @修改人和其它資訊 */ public class FadeShare implements Runnable{

共享

一、偽共享的定義: 偽共享的非標準定義為:快取系統中是以快取行(cache line)為單位儲存的,當多執行緒修改互相獨立的變數時,如果這些變數共享同一個快取行,就會無意中影響彼此的效能,這就是偽共享。 二、CPU快取機制 CPU 快取的百度百科定義為: CPU 快取(Cache Memory)是位於

@sun.misc.Contended 解決共享問題

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

Java 7與共享的新仇舊恨

我有個疑問,就是怎麼才能確保底層能夠正確的填充? 下面是我通過工具JOL生成的物件佈局: # Running 64-bit HotSpot VM. # Using compressed oop with 3-bit shift. # Using compressed klass with 3-bit

從Java視角理解系統結構(三)共享

從Java視角理解系統結構連載, 關注我的微博(連結)瞭解最新動態 從我的前一篇博文中, 我們知道了CPU快取及快取行的概念, 同時用一個例子說明了編寫單執行緒Java程式碼時應該注意的問題. 下面我們討論更為複雜, 而且更符合現實情況的多核程式設計時將會碰到的問題. 這些問題更容易犯, 連j

共享(False Sharing)

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

有助於減少共享的@Contended註解

原文連結 作者:Dave 譯者:卓二妹 校對:丁一 詳細描述看Aleksey Shipilev這封郵件 —— 我們期待@Contended已久。JVM會自動為物件欄位進行記憶體佈局。通常JVM會這樣做:(a)將物件的域按從大到小的順序排列,以優化佔用的空間;(b)打包引用型別的欄位,以便垃圾收

電腦科學中抽象的好處與問題—共享例項分析

David John Wheeler有一句名言“電腦科學中的任何問題都可以通過加上一層間接層來解決”,一層不夠就再加一層。後半句是我加的 (* ̄︶ ̄) ,雖然有點玩笑的意思,但是也的確能說明一些問題。電腦科學的確是靠著一層又一層的抽象與封裝解決了巨量的問題。 我們來簡單回顧一下: 開始的

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

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

多執行緒程式設計:共享以及其解決方案

首先本文是根據多篇部落格的整合而來,依照本人的理解所寫 1.基本概念的瞭解 回到正題,建議先從下面的部落格連結看起以便對下列概念有個基本的瞭解: 1)CPU快取 2)MESI協議以及RFO請求 3)快取行 具體部落格連結:https://www.cnbl

共享(False Sharing)

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

併發不得不說的共享

前言 可謂是一入併發深似海,看得越多,發現自己懂的越少,總感覺自己只是瞭解了其冰山一角。但是在研究的過程中越來越感受到一些框架的設計之美,很細膩的趕腳。同時也讓我get到了新的知識點。 CPU快取 在正式進入正題之前,必須得先說說快取這個概念。對於快取這個概念相信大多數程式猿都不會很陌生,在大