太牛逼了!自從項(xiàng)目中用了Disruptor之后,性能提升了2.5倍
一、CPU Cache

現(xiàn)在的 CPU 都是由多個(gè)處理器,每個(gè)處理器由多個(gè)核心構(gòu)成。一個(gè)處理器對應(yīng)一個(gè)物理插槽,不同的處理器間通過 QPI 總線相連。一個(gè)處理器間的多核共享 L3 Cache。一個(gè)核包含寄存器、L1 Cache、L2 Cache,下圖是Intel Sandy Bridge CPU架構(gòu):

二、緩存行與偽共享

現(xiàn)在假設(shè)多線程情況下,線程 A 的執(zhí)行者 CPU Core-1 讀取 arr[1],首先查詢緩存,緩存沒有命中,緩存就會(huì)去內(nèi)存中加載。從內(nèi)存中讀取 arr[1] 起的連續(xù)的 64 個(gè)字節(jié)地址到緩存中,組成緩存行。由于從arr[1] 起,arr 的長度不足夠 64 個(gè)字節(jié),只夠 56 個(gè)字節(jié)。假設(shè)最后 8 個(gè)字節(jié)內(nèi)存地址上存儲(chǔ)的是對象 bar,那么對象 bar 也會(huì)被一起加載到緩存行中。

三、Disruptor 緩存行填充
public?class?Sequence?extends?RhsPadding?{
????private?static?final?long?VALUE_OFFSET;
????
????static?{
????????VALUE_OFFSET?=?UNSAFE.objectFieldOffset(Value.class.getDeclaredField("value"));
????????...
????}
????...
}
class?RhsPadding?extends?Value?{
????protected?long?p9,?p10,?p11,?p12,?p13,?p14,?p15;
}
class?Value?extends?LhsPadding?{
????protected?volatile?long?value;
}
class?LhsPadding?{
????protected?long?p1,?p2,?p3,?p4,?p5,?p6,?p7;
}
如下圖所示,其中 V 就是 Value 類的 value,P 為 value 前后填充的無意義 long 型變量,U 為其它無關(guān)的變量。不論什么情況下,都能保證 V 不和其他無關(guān)的變量處于同一緩存行中,這樣 V 就不會(huì)被其他無關(guān)的變量所影響。

此處以 Disruptor 的 RingBuffer 為例,最左邊的 7 個(gè) long 型變量被定義在頂級父類 RingBufferPad 中,最右邊的 7 個(gè) long 型變量被定義在 RingBuffer 的最后一行變量定義中,這樣所有的需要獨(dú)占的變量都被左右 long 型給包圍,確保會(huì)獨(dú)占緩存行。
public?final?class?RingBuffer<E>?extends?RingBufferFields<E>?implements?Cursored,?EventSequencer<E>,?EventSink<E>?{
????public?static?final?long?INITIAL_CURSOR_VALUE?=?Sequence.INITIAL_VALUE;
????protected?long?p1,?p2,?p3,?p4,?p5,?p6,?p7;
????...
}
abstract?class?RingBufferFields<E>?extends?RingBufferPad
{
????...
}
abstract?class?RingBufferPad?{
????protected?long?p1,?p2,?p3,?p4,?p5,?p6,?p7;
}
四、@Contended
//?類前加上代表整個(gè)類的每個(gè)變量都會(huì)在單獨(dú)的cache?line中
@sun.misc.Contended
public?class?ContendedData?{
????int?value;
????long?modifyTime;
????boolean?flag;
????long?createTime;
????char?key;
}
//?同一?groupName?在同一緩存行
public?class?ContendedGroupData?{
????@sun.misc.Contended("group1")
????int?value;
????@sun.misc.Contended("group1")
????long?modifyTime;
????@sun.misc.Contended("group2")
????boolean?flag;
????@sun.misc.Contended("group3")
????long?createTime;
????@sun.misc.Contended("group3")
????char?key;
}
public?class?Thread?implements?Runnable?{
????...
????//?The?following?three?initially?uninitialized?fields?are?exclusively
????//?managed?by?class?java.util.concurrent.ThreadLocalRandom.?These
????//?fields?are?used?to?build?the?high-performance?PRNGs?in?the
????//?concurrent?code,?and?we?can?not?risk?accidental?false?sharing.
????//?Hence,?the?fields?are?isolated?with?@Contended.
????/**?The?current?seed?for?a?ThreadLocalRandom?*/
????@sun.misc.Contended("tlr")
????long?threadLocalRandomSeed;
????/**?Probe?hash?value;?nonzero?if?threadLocalRandomSeed?initialized?*/
????@sun.misc.Contended("tlr")
????int?threadLocalRandomProbe;
????/**?Secondary?seed?isolated?from?public?ThreadLocalRandom?sequence?*/
????@sun.misc.Contended("tlr")
????int?threadLocalRandomSecondarySeed;
????
????...
}
五、速度測試

來源:https://jitwxs.cn/13836b16.html
版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會(huì)標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會(huì)立即刪除并表示歉意。謝謝!

