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

剖析Disruptor:為什么會這么快?(三)偽共享

開發 后端
緩存行上的寫競爭是運行在SMP系統中并行線程實現可伸縮性最重要的限制因素。有 人將偽共享描述成無聲的性能殺手,因為從代碼中很難看清楚是否會出現偽共享。

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

為了讓可伸縮性與線程數呈線性關系,就必須確保不會有兩個線程往同一個變量或緩存行中寫。兩個線程寫同一個變量可以在代碼中發現。為了確定互相獨立的變量 是否共享了同一個緩存行,就需要了解內存布局,或找個工具告訴我們。Intel VTune就是這樣一個分析工具。本文中我將解釋Java對象的內存布局以及我們該如何填充緩存行以避免偽共享。

cache-line.png

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

Java內存布局(Java Memory Layout)

對于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. <子類字段重復上述順序>

了解這些之后就可以在任意字段間用7個long來填充緩存行。在Disruptor里我們對RingBuffer的cursor和BatchEventProcessor的序列進行了緩存行填充。

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

  1. public final class FalseSharing 
  2.     implements Runnable 
  3.     public final static int NUM_THREADS = 4// change 
  4.     public final static long ITERATIONS = 500L * 1000L * 1000L; 
  5.     private final int arrayIndex; 
  6.   
  7.     private static VolatileLong[] longs = new VolatileLong[NUM_THREADS]; 
  8.     static 
  9.     { 
  10.         for (int i = 0; i < longs.length; i++) 
  11.         { 
  12.             longs[i] = new VolatileLong(); 
  13.         } 
  14.     } 
  15.   
  16.     public FalseSharing(final int arrayIndex) 
  17.     { 
  18.         this.arrayIndex = arrayIndex; 
  19.     } 
  20.   
  21.     public static void main(final String[] args) throws Exception 
  22.     { 
  23.         final long start = System.nanoTime(); 
  24.         runTest(); 
  25.         System.out.println("duration = " + (System.nanoTime() - start)); 
  26.     } 
  27.   
  28.     private static void runTest() throws InterruptedException 
  29.     { 
  30.         Thread[] threads = new Thread[NUM_THREADS]; 
  31.   
  32.         for (int i = 0; i < threads.length; i++) 
  33.         { 
  34.             threads[i] = new Thread(new FalseSharing(i)); 
  35.         } 
  36.   
  37.         for (Thread t : threads) 
  38.         { 
  39.             t.start(); 
  40.         } 
  41.   
  42.         for (Thread t : threads) 
  43.         { 
  44.             t.join(); 
  45.         } 
  46.     } 
  47.   
  48.     public void run() 
  49.     { 
  50.         long i = ITERATIONS + 1
  51.         while (0 != --i) 
  52.         { 
  53.             longs[arrayIndex].value = i; 
  54.         } 
  55.     } 
  56.   
  57.     public final static class VolatileLong 
  58.     { 
  59.         public volatile long value = 0L; 
  60.         public long p1, p2, p3, p4, p5, p6; // comment out 
  61.     } 

結果(Results)

運行上面的代碼,增加線程數以及添加/移除緩存行的填充,下面的圖2描述了我得到的結果。這是在我4核Nehalem上測得的運行時間。

duration.png

從不斷上升的測試所需時間中能夠明顯看出偽共享的影響。沒有緩存行競爭時,我們幾近達到了隨著線程數的線性擴展。

這并不是個完美的測試,因為我們不能確定這些VolatileLong會布局在內存的什么位置。它們是獨立的對象。但是經驗告訴我們同一時間分配的對象趨向集中于一塊。

所以你也看到了,偽共享可能是無聲的性能殺手。

原文鏈接:http://ifeve.com/false-sharing/

譯文鏈接:http://ifeve.com/falsesharing/

責任編輯:陳四芳 來源: ifeve.com
相關推薦

2013-06-19 10:55:40

Disruptor并發框架

2013-06-17 14:41:10

Disruptor并發編程

2013-06-18 10:30:45

Disruptor框架

2020-03-30 15:05:46

Kafka消息數據

2024-02-26 21:15:20

Kafka緩存參數

2020-02-27 15:44:41

Nginx服務器反向代理

2020-02-27 21:03:30

調度器架構效率

2023-08-29 07:46:08

Redis數據ReHash

2020-10-15 09:19:36

Elasticsear查詢速度

2021-05-27 20:56:51

esbuild 工具JavaScript

2012-08-17 10:01:07

云計算

2023-03-21 08:02:36

Redis6.0IO多線程

2020-10-21 09:17:52

Redis面試內存

2017-06-06 16:30:55

戴爾交付保障

2020-04-27 07:13:37

Nginx底層進程

2022-01-04 08:54:32

Redis數據庫數據類型

2023-11-02 10:22:29

gRPC后端通信

2021-03-18 14:34:34

達達集團京東云電商

2024-11-26 08:52:34

SQL優化Kafka

2024-07-24 08:38:07

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99r在线 | www.国产| 狠狠涩 | 欧美xxxx性 | 亚洲色图插插插 | 欧美成人一级视频 | 日韩电影中文字幕在线观看 | 久久久亚洲一区 | 在线观看av网站 | 欧美日韩久久久久 | 国产一区二区不卡 | www.亚洲.com| 亚洲精品成人免费 | 亚洲成人精选 | 国产视频亚洲视频 | 在线观看精品视频网站 | 紧缚调教一区二区三区视频 | 国产资源在线视频 | 精品国产欧美在线 | 色综网| 综合精品 | 国产91精品久久久久久久网曝门 | a国产视频| 中文字幕一区二区三区四区五区 | 久久久国产精品 | 99这里只有精品 | 宅女噜噜66国产精品观看免费 | 国产一区在线看 | 国产一级片在线播放 | 特黄特黄a级毛片免费专区 av网站免费在线观看 | 国产一区久久久 | 久久国产精品视频免费看 | a视频在线观看 | 国产视频中文字幕 | 国产成人综合网 | 日韩精品在线看 | 亚洲第1页| 草久久| 波多野结衣一区二区三区在线观看 | 日韩av免费在线电影 | 69精品久久久久久 |