成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

自從項目用了Disruptor,性能提升了2.5倍!

開發(fā) 后端
在計算機中,CPU 的速度遠高于主存的速度,而主存的速度又遠高于磁盤的速度。為了解決不同存儲部件的速度不對等問題,讓高速設備充分發(fā)揮性能,引入了多級緩存機制。

 一、CPU Cache

存儲設備往往是速度越快價格越昂貴,速度越快價格越低廉。

在計算機中,CPU 的速度遠高于主存的速度,而主存的速度又遠高于磁盤的速度。為了解決不同存儲部件的速度不對等問題,讓高速設備充分發(fā)揮性能,引入了多級緩存機制。

為了解決內存和 CPU 的速度不匹配問題,相繼引入了 L1 Cache、L2 Cache、L3 Cache,數(shù)字越小,容量越小,速度越快,位置越接近 CPU。

現(xiàn)在的 CPU 都是由多個處理器,每個處理器由多個核心構成。一個處理器對應一個物理插槽,不同的處理器間通過 QPI 總線相連。

一個處理器間的多核共享 L3 Cache。一個核包含寄存器、L1 Cache、L2 Cache,下圖是Intel Sandy Bridge CPU架構:

二、緩存行與偽共享

緩存中的數(shù)據(jù)并不是獨立的進行存儲的,它的最小存儲單位是緩存行,緩存行的大小是2的整數(shù)冪個字節(jié),最常見的緩存行大小是 64 字節(jié)。CPU 為了執(zhí)行的高效,會在讀取某個對象時,從內存上加載 64 的整數(shù)倍的長度,來補齊緩存行。

以 Java 的 long 類型為例,它是 8 個字節(jié),假設我們存在一個長度為 8 的 long 數(shù)組 arr,那么CPU 在讀取 arr[0] 時,首先查詢緩存,緩存沒有命中,緩存就會去內存中加載。

由于緩存的最小存儲單位是緩存行,64 字節(jié),且數(shù)組的內存地址是連續(xù)的,則將 arr[0] 到 arr[7] 加載到緩存中。后續(xù) CPU 查詢 arr[6] 時候也可以直接命中緩存。

現(xiàn)在假設多線程情況下,線程 A 的執(zhí)行者 CPU Core-1 讀取 arr[1],首先查詢緩存,緩存沒有命中,緩存就會去內存中加載。

從內存中讀取 arr[1] 起的連續(xù)的 64 個字節(jié)地址到緩存中,組成緩存行。由于從arr[1] 起,arr 的長度不足夠 64 個字節(jié),只夠 56 個字節(jié)。假設最后 8 個字節(jié)內存地址上存儲的是對象 bar,那么對象 bar 也會被一起加載到緩存行中。

現(xiàn)在有另一個線程 B,線程 B 的執(zhí)行者 CPU Core-2 去讀取對象 bar,首先查詢緩存,發(fā)現(xiàn)命中了,因為 Core-1 在讀取 arr 數(shù)組的時候也順帶著把 bar 加載到了緩存中。

這就是緩存行共享,聽起來不錯,但是一旦牽扯到了寫入操作就不妙了。

假設 Core-1 想要更新 arr[7] 的值,根據(jù) CPU 的 MESI 協(xié)議,那么它所屬的緩存行就會被標記為失效。因為它需要告訴其他的 Core,這個 arr[7] 的值已經被更新了,緩存已經不再準確了,你必須得重新去內存拉取。但是由于緩存的最小單元是緩存行,因此只能把 arr[7] 所在的一整行給標識為失效。

此時 Core-2 就會很郁悶了,剛剛還能夠從緩存中讀取到對象 bar,現(xiàn)在再讀取卻被告知緩存行失效,必須得去內存重新拉取,延緩了 Core-2 的執(zhí)行效率。

這就是緩存?zhèn)喂蚕韱栴},兩個毫無關聯(lián)的線程執(zhí)行,一個線程卻因為另一個線程的操作,導致緩存失效。這兩個線程其實就是對同一緩存行產生了競爭,降低了并發(fā)性。

三、Disruptor 緩存行填充

Disruptor 為了解決偽共享問題,使用的方法是緩存行填充。這是一種以空間換時間的策略,主要思想就是通過往對象中填充無意義的變量,來保證整個對象獨占緩存行。

舉個例子,以 Disruptor 中的 Sequence 為例,在 volatile long value 的前后各放置了 7 個 long 型變量,確保 value 獨占一個緩存行。 

  1. public class Sequence extends RhsPadding {  
  2.     private static final long VALUE_OFFSET;   
  3.     static {  
  4.         VALUE_OFFSET = UNSAFE.objectFieldOffset(Value.class.getDeclaredField("value"));  
  5.         ... 
  6.     }  
  7.     ...  
  8.  
  9. class RhsPadding extends Value {  
  10.     protected long p9, p10, p11, p12, p13, p14, p15;  
  11.  
  12. class Value extends LhsPadding {  
  13.     protected volatile long value;  
  14.  
  15. class LhsPadding {  
  16.     protected long p1, p2, p3, p4, p5, p6, p7;  

如下圖所示,其中 V 就是 Value 類的 value,P 為 value 前后填充的無意義 long 型變量,U 為其它無關的變量。不論什么情況下,都能保證 V 不和其他無關的變量處于同一緩存行中,這樣 V 就不會被其他無關的變量所影響。

這里的 V 也不限定為 long 類型,其實只要對象的大小大于等于8個字節(jié),通過前后各填充 7 個 long 型變量,就一定能夠保證獨占緩存行。

此處以 Disruptor 的 RingBuffer 為例,最左邊的 7 個 long 型變量被定義在頂級父類 RingBufferPad 中,最右邊的 7 個 long 型變量被定義在 RingBuffer 的最后一行變量定義中,這樣所有的需要獨占的變量都被左右 long 型給包圍,確保會獨占緩存行。 

  1. public final class RingBuffer<E> extends RingBufferFields<E> implements Cursored, EventSequencer<E>, EventSink<E> {  
  2.     public static final long INITIAL_CURSOR_VALUE = Sequence.INITIAL_VALUE;  
  3.     protected long p1, p2, p3, p4, p5, p6, p7;  
  4.     ...  
  5. abstract class RingBufferFields<E> extends RingBufferPad  
  6.  
  7.     ...  
  8.  
  9. abstract class RingBufferPad {  
  10.     protected long p1, p2, p3, p4, p5, p6, p7;  

四、@Contended

在 JDK 1.8 中,提供了 @sun.misc.Contended 注解,使用該注解就可以讓變量獨占緩存行,不再需要手動填充了。另外,關注公眾號Java技術棧,在后臺回復:Java,可以獲取我整理的 Java 1.8 系列教程,非常齊全。

注意,JVM 需要添加參數(shù) -XX:-RestrictContended 才能開啟此功能。46張PPT弄懂JVM、GC算法和性能調優(yōu),分享給你。

如果該注解被定義在了類上,表示該類的每個變量都會獨占緩存行;如果被定義在了變量上,通過指定 groupName,相同的 groupName 會獨占同一緩存行。 

  1. // 類前加上代表整個類的每個變量都會在單獨的cache line中  
  2. @sun.misc.Contended  
  3. public class ContendedData {  
  4.     int value;  
  5.     long modifyTime;  
  6.     boolean flag;  
  7.     long createTime;  
  8.     char key;  
  9.  
  10. // 同一 groupName 在同一緩存行  
  11. public class ContendedGroupData {  
  12.     @sun.misc.Contended("group1")  
  13.     int value;  
  14.     @sun.misc.Contended("group1")  
  15.     long modifyTime;  
  16.     @sun.misc.Contended("group2")  
  17.     boolean flag;  
  18.     @sun.misc.Contended("group3")  
  19.     long createTime;  
  20.     @sun.misc.Contended("group3")  
  21.     char key;  

@Contended 在 JDK 源碼中已經有所應用,以 Thread 類為例,為了保證多線程情況下隨機數(shù)的操作不會產生偽共享,相關的變量被設置為同一 groupName。 

  1. public class Thread implements Runnable {  
  2.     ...  
  3.     // The following three initially uninitialized fields are exclusively  
  4.     // managed by class java.util.concurrent.ThreadLocalRandom. These  
  5.     // fields are used to build the high-performance PRNGs in the  
  6.     // concurrent code, and we can not risk accidental false sharing.  
  7.     // Hence, the fields are isolated with @Contended.  
  8.     /** The current seed for a ThreadLocalRandom */  
  9.     @sun.misc.Contended("tlr")  
  10.     long threadLocalRandomSeed;  
  11.     /** Probe hash value; nonzero if threadLocalRandomSeed initialized */  
  12.     @sun.misc.Contended("tlr")  
  13.     int threadLocalRandomProbe;  
  14.     /** Secondary seed isolated from public ThreadLocalRandom sequence */  
  15.     @sun.misc.Contended("tlr")  
  16.     int threadLocalRandomSecondarySeed;  
  17.      ...  

五、速度測試

將 volatile long value 封裝為對象,四線程并行,每個線程循環(huán) 1 億次,對 value 進行更新操作,測試緩存行對速度的影響。

  •  CPU:AMD 3600 3.6 GHz
  •  Memory:16 GB

 

 

責任編輯:龐桂玉 來源: Java技術棧
相關推薦

2024-10-29 08:21:05

2025-05-27 01:55:00

TypeScript開發(fā)者項目

2022-04-21 07:51:51

場景JavaSQL

2024-07-17 08:25:44

2021-08-02 10:50:57

性能微服務數(shù)據(jù)

2021-09-13 10:25:35

開發(fā)技能代碼

2023-08-08 14:56:27

ParcelRustDemo

2022-09-09 09:33:14

支付寶代碼性能

2022-09-21 17:43:29

Kafka底層網絡

2024-12-11 07:59:02

2021-12-27 06:57:40

Maven工具性能

2023-03-22 13:53:26

芯片英偉達

2021-03-08 08:02:40

IDEA插件JSON

2025-06-05 00:00:00

項目接口合并

2022-12-29 08:43:43

項目接口請求

2011-07-01 10:11:39

2022-09-27 18:19:32

Java數(shù)據(jù)結構

2023-10-20 08:12:00

JDK21線程池配置

2024-12-13 13:58:53

2025-05-09 02:00:00

代碼接口吞吐量
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.中文字幕av | 毛片免费在线观看 | 中文亚洲视频 | 久久伊人久久 | 久久黄网 | 久久久久网站 | av网站免费观看 | 国产一区二区三区四区五区加勒比 | 欧美成人不卡 | 伊人狠狠操 | 久久久久成人精品免费播放动漫 | 成人免费一区二区三区视频网站 | 不卡一区| 国产成人精品一区二 | 亚洲精品综合一区二区 | 免费黄色a视频 | 综合久久av | 国产成人自拍一区 | 日韩一三区 | 精品久久久久久久久久久久 | 日韩精品免费在线观看 | 成人久久久 | 欧美一级久久 | 亚洲九九色 | www国产成人免费观看视频,深夜成人网 | 97在线超碰 | 99久久精品国产一区二区三区 | 亚洲精品成人 | 国产高清视频在线播放 | 一区二区三区国产在线观看 | 日本不卡视频 | 日韩欧美三级 | 一本色道精品久久一区二区三区 | 成人av资源在线 | 一级片免费视频 | 青草青草久热精品视频在线观看 | 中文字幕在线精品 | 北条麻妃一区二区三区在线视频 | 亚洲视频在线观看免费 | 国产一级视屏 | 天天操综合网站 |