原文連接:http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-why-its-so-fast_22.html 需FQhtml
Martin 和 Mike 的 QCon presentation 演講中給出了一些緩存未命中的消耗數據:數組
從CPU到 | 大約須要的 CPU 週期 | 大約須要的時間 |
主存 | 約60-80納秒 | |
QPI 總線傳輸 (between sockets, not drawn) |
約20ns | |
L3 cache | 約40-45 cycles, | 約15ns |
L2 cache | 約10 cycles, | 約3ns |
L1 cache | 約3-4 cycles, | 約1ns |
寄存器 | 1 cycle |
head;同時
你的類中有另外一個變量緊挨着它,暫時稱它爲
tail
。如今,當你加載
head
到緩存的時候,你也免費加載了
tail
。
head中保存的內容也
正被消費者(譯註:和生產者不在同一個內核中)消費。這兩個變量並沒有直接聯繫,但須要被這兩個線程使用,且這兩個線程運行在不一樣的內核(譯註:這裏是指物理上的內核,即多核CPU)中。
head
的值。緩存中的值和內存中的值都被更新了,而其餘全部存儲
head
的緩存行都會都會失效,由於其它緩存中
head
不是最新值了。而咱們必須以整個緩存行做爲單位來處理,不能只把
head
標記爲無效。
head
你也會獲得
tail
,並且每次你訪問
tail
,你也會獲得
head
。這一切都在後臺發生,而且沒有任何編譯警告會告訴你,你正在寫一個併發訪問效率很低的代碼。
public long p1, p2, p3, p4, p5, p6, p7; // cache line padding private volatile long cursor = INITIAL_CURSOR_VALUE; public long p8, p9, p10, p11, p12, p13, p14; // cache line padding
(譯註:先後各七位填充字段,保證cursor[1]在緩衝行中任意位置,其周圍都有足夠的填充字段)緩存
Entry
類中也值得這樣作,若是你有不一樣的消費者往不一樣的字段寫入,你須要確保各個字段間不會出現僞共享。