一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法
【專(zhuān)利摘要】本發(fā)明公開(kāi)了一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,采用環(huán)型數(shù)組作為數(shù)據(jù)緩沖區(qū),有利于緩存預(yù)讀,同時(shí)避免了鏈表結(jié)構(gòu)所帶來(lái)的每次節(jié)點(diǎn)操作都需要申請(qǐng)或釋放內(nèi)存的弊端,提高了效率;對(duì)于多生產(chǎn)者單消費(fèi)者模型的并發(fā)控制問(wèn)題,采用CAS和內(nèi)存屏障保證互斥,不使用加鎖的方式,避免鎖的低效帶來(lái)的性能劣化;對(duì)于無(wú)鎖技術(shù)中常見(jiàn)的ABA問(wèn)題,采用雙保險(xiǎn)的CAS技術(shù),避免ABA問(wèn)題的發(fā)生;對(duì)于偽共享問(wèn)題,在頭指針、尾指針和容量三個(gè)變量間使用緩沖行填充方法,避免頭指針、尾指針和容量三個(gè)變量在同一個(gè)緩沖行中,造成偽共享問(wèn)題;同時(shí)將數(shù)組長(zhǎng)度設(shè)為2的指數(shù)倍,采用“與操作”的位運(yùn)算來(lái)獲取數(shù)組下標(biāo),提高了整體效率。
【專(zhuān)利說(shuō)明】一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法
[0001]
【技術(shù)領(lǐng)域】
[0002]本發(fā)明屬于計(jì)算機(jī)軟件工程【技術(shù)領(lǐng)域】,涉及一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法。
[0003]
【背景技術(shù)】
[0004]在一個(gè)消息驅(qū)動(dòng)的系統(tǒng)中,消息處理機(jī)制是系統(tǒng)的重點(diǎn)和難點(diǎn)問(wèn)題,消息處理機(jī)制的優(yōu)劣影響到整個(gè)系統(tǒng)的穩(wěn)定性和效率。
[0005]現(xiàn)有的消息處理機(jī)制一般都是基于隊(duì)列(采用鏈表實(shí)現(xiàn))和鎖算法為核心來(lái)實(shí)現(xiàn)的。消息隊(duì)列采用鏈表結(jié)構(gòu)來(lái)保存。對(duì)于多線(xiàn)程對(duì)共享數(shù)據(jù)的操作采用信號(hào)量和鎖來(lái)解決同步和互斥問(wèn)題。
[0006]現(xiàn)有的機(jī)制有幾點(diǎn)對(duì)性能有較大影響: (I)鏈表節(jié)點(diǎn)分散,不在同一片存儲(chǔ)區(qū)域,不利于緩存預(yù)讀。
[0007](2)鏈表節(jié)點(diǎn)每次操作時(shí)需要申請(qǐng)或釋放內(nèi)存,比較低效。
[0008](3)習(xí)慣的編程方式導(dǎo)致頭指針、尾指針和容量三個(gè)變量常常在一個(gè)緩存行中,造成偽共享問(wèn)題。
[0009](4)大量的鎖操作造成效率低下。
[0010]
【發(fā)明內(nèi)容】
[0011]本發(fā)明是基于現(xiàn)有需求,改變傳統(tǒng)的消息處理機(jī)制,采用基于環(huán)形數(shù)組緩沖區(qū)的無(wú)鎖并發(fā)機(jī)制來(lái)進(jìn)行消息處理,提出了一種在確保系統(tǒng)穩(wěn)定性的前提下、盡量?jī)?yōu)化性能的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法。
[0012]本發(fā)明所采用的技術(shù)方案是:一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:儲(chǔ)存消息數(shù)據(jù)的緩沖區(qū)采用環(huán)形數(shù)組結(jié)構(gòu),而不是采用鏈表結(jié)構(gòu),使數(shù)據(jù)存儲(chǔ)在同一片存儲(chǔ)區(qū)域,便于緩存預(yù)讀,同時(shí)避免鏈表節(jié)點(diǎn)每次操作時(shí)所需要申請(qǐng)或釋放內(nèi)存操作,提高效率。
[0013]緩沖區(qū)的中心數(shù)據(jù)結(jié)構(gòu)是一個(gè)基于定長(zhǎng)數(shù)組的環(huán)形隊(duì)列。在數(shù)組創(chuàng)建時(shí)可以預(yù)先分配好空間,插入新元素時(shí)只要將新元素?cái)?shù)據(jù)拷貝到已經(jīng)分配好的內(nèi)存中即可,在刪除舊元素時(shí)也不需要釋放內(nèi)存空間。使用環(huán)形數(shù)組的緩沖區(qū)避免了頻繁的內(nèi)存操作,同時(shí)對(duì)數(shù)組的元素訪(fǎng)問(wèn)對(duì)CPU緩存是非常友好的。
[0014]作為優(yōu)選,對(duì)于多生產(chǎn)者單消費(fèi)者模型的并發(fā)控制問(wèn)題,采用CAS和內(nèi)存屏障保證互斥,不使用加鎖的方式,避免鎖的低效帶來(lái)的性能劣化。
[0015]采用CAS和內(nèi)存屏障代替互斥鎖來(lái)保證資源共享時(shí)的互斥。鎖是用來(lái)做并發(fā)最簡(jiǎn)單的方式,當(dāng)然其代價(jià)也是最高的。內(nèi)核態(tài)的鎖上鎖的時(shí)候需要操作系統(tǒng)進(jìn)行一次上下文切換,等待鎖的線(xiàn)程會(huì)被掛起直至鎖釋放。在上下文切換的時(shí)候,CPU之前緩存的指令和數(shù)據(jù)都將失效,對(duì)性能有很大的損失。用戶(hù)態(tài)的鎖雖然避免了這些問(wèn)題,但是往往是通過(guò)自旋鎖來(lái)實(shí)現(xiàn)(自旋即忙等待),而自旋在競(jìng)爭(zhēng)激烈的時(shí)候開(kāi)銷(xiāo)非常大(因?yàn)槊Φ却恢痹谙腃PU資源)。不使用鎖,使用CAS嚴(yán)格意義上說(shuō)仍然是使用鎖,因?yàn)镃AS本質(zhì)上也是一種樂(lè)觀(guān)鎖,只不過(guò)是CPU級(jí)別指令,不涉及到操作系統(tǒng),所以效率很高。使用CAS時(shí)不像上鎖那樣需要一次上下文切換,只需要處理器鎖住它的指令流水線(xiàn)來(lái)保證原子性。但CAS并不是無(wú)開(kāi)銷(xiāo)的,它會(huì)涉及到對(duì)指令pipeline加鎖,并且會(huì)用到內(nèi)存屏障(用來(lái)刷新內(nèi)存狀態(tài),簡(jiǎn)單理解就是把緩存中,寄存器中的數(shù)據(jù)同步到內(nèi)存中去)?,F(xiàn)代CPU是亂序執(zhí)行的,也就是程序順序與實(shí)際的執(zhí)行順序很可能是不一致的。在單線(xiàn)程執(zhí)行時(shí)這不是個(gè)問(wèn)題,但是在多線(xiàn)程環(huán)境下這種亂序就可能會(huì)對(duì)執(zhí)行結(jié)果產(chǎn)生很大的影響了。內(nèi)存屏障提供了一種控制程序執(zhí)行順序的手段。
[0016]作為優(yōu)選,為避免ABA問(wèn)題,采用雙保險(xiǎn)的CAS技術(shù),將計(jì)算機(jī)能一次操作的存儲(chǔ)區(qū)域分為高地址部分和低地址部分,高地址部分為標(biāo)志位,低地址部分為數(shù)據(jù)位,同時(shí)對(duì)標(biāo)志位和數(shù)據(jù)位進(jìn)行CAS操作,避免ABA問(wèn)題發(fā)生。
[0017]在入隊(duì)列時(shí)采用雙保險(xiǎn)的CAS是為了避免ABA問(wèn)題。所謂ABA問(wèn)題簡(jiǎn)單理解就是:
(1)進(jìn)程Pl在共享變量中讀到值為A;
(2)Pl被搶占了,進(jìn)程P2執(zhí)行;
(3)P2把共享變量里的值從A改成了 B,再改回到A,此時(shí)被Pl搶占;
(4)Pl回來(lái)看到共享變量里的值沒(méi)有被改變,于是繼續(xù)執(zhí)行。
[0018]雖然Pl以為變量值沒(méi)有改變,繼續(xù)執(zhí)行了,但是這個(gè)會(huì)引發(fā)一些潛在的問(wèn)題。ABA問(wèn)題最容易發(fā)生在無(wú)鎖的算法中。
[0019]作為優(yōu)選,對(duì)于偽共享問(wèn)題,在頭指針、尾指針和容量三個(gè)變量間使用緩沖行填充方法,避免頭指針、尾指針和容量三個(gè)變量在同一個(gè)緩沖行中,造成偽共享問(wèn)題。
[0020]在頭指針、尾指針和容量三個(gè)變量間使用緩沖行填充方法可以避免偽共享問(wèn)題。緩存行是指CPU在做緩存的時(shí)候有個(gè)最小緩存單元,在同一個(gè)單元內(nèi)的數(shù)據(jù)被同時(shí)被加載到緩存中,充分利用緩存行可以大大降低數(shù)據(jù)讀寫(xiě)的延遲,錯(cuò)誤利用緩存行也會(huì)導(dǎo)致緩存不同替換,反復(fù)失效。緩存系統(tǒng)中是以緩存行為單位存儲(chǔ)的。當(dāng)多線(xiàn)程修改互相獨(dú)立的變量時(shí),如果這些變量共享同一個(gè)緩存行,就會(huì)無(wú)意中影響彼此的性能,這就是偽共享。緩存行上的寫(xiě)競(jìng)爭(zhēng)是運(yùn)行在對(duì)稱(chēng)式多處理器系統(tǒng)中并行線(xiàn)程實(shí)現(xiàn)可伸縮性最重要的限制因素。
[0021]作為優(yōu)選,所述的環(huán)形數(shù)組長(zhǎng)度設(shè)為2的指數(shù)倍,采用“與操作”的位運(yùn)算代替“取余操作”來(lái)獲取數(shù)組下標(biāo),利用計(jì)算機(jī)“與操作”的效率高于“取余操作”的特性來(lái)提高整體效率。
[0022]關(guān)于環(huán)形數(shù)組的大小選擇有一個(gè)講究,一般對(duì)環(huán)形隊(duì)列中取下標(biāo)通常會(huì)用到取余操作,在大部分處理器上,取余操作并不高效。因此可以將數(shù)組大小設(shè)定為2的指數(shù)倍,這樣計(jì)算余數(shù)只需要通過(guò)位操作“index & ( size -1 ) ”就能夠得到實(shí)際的數(shù)組下標(biāo)。
[0023]本發(fā)明是一種在確保系統(tǒng)穩(wěn)定性的前提下、盡量?jī)?yōu)化性能的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法。
[0024]
【專(zhuān)利附圖】
【附圖說(shuō)明】
[0025]圖1:為本發(fā)明實(shí)施例中寫(xiě)入數(shù)據(jù)流程圖;
圖2:為本發(fā)明實(shí)施例中讀取數(shù)據(jù)流程圖;
圖3:為本發(fā)明實(shí)施例中ABA問(wèn)題示意圖;
圖4:為本發(fā)明實(shí)施例中為解決ABA問(wèn)題設(shè)計(jì)的存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)示意圖;
圖5:為本發(fā)明實(shí)施例中ABA問(wèn)題解決流程示意圖。
[0026]
【具體實(shí)施方式】
[0027]為了便于本領(lǐng)域普通技術(shù)人員理解和實(shí)施本發(fā)明,下面結(jié)合附圖及實(shí)施例對(duì)本發(fā)明作進(jìn)一步的詳細(xì)描述,應(yīng)當(dāng)理解,此處所描述的實(shí)施示例僅用于說(shuō)明和解釋本發(fā)明,并不用于限定本發(fā)明。
[0028]本發(fā)明所采用的技術(shù)方案是:一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,儲(chǔ)存消息數(shù)據(jù)的緩沖區(qū)采用環(huán)形數(shù)組結(jié)構(gòu),而不是采用鏈表結(jié)構(gòu),使數(shù)據(jù)存儲(chǔ)在同一片存儲(chǔ)區(qū)域,便于緩存預(yù)讀,同時(shí)避免鏈表節(jié)點(diǎn)每次操作時(shí)所需要申請(qǐng)或釋放內(nèi)存操作,提高效率;環(huán)形數(shù)組長(zhǎng)度設(shè)為2的指數(shù)倍,采用“與操作”的位運(yùn)算代替“取余操作”來(lái)獲取數(shù)組下標(biāo),利用計(jì)算機(jī)“與操作”的效率高于“取余操作”的特性來(lái)提高整體效率;對(duì)于多生產(chǎn)者單消費(fèi)者模型的并發(fā)控制問(wèn)題,采用CAS和內(nèi)存屏障保證互斥,不使用加鎖的方式,避免鎖的低效帶來(lái)的性能劣化;為避免ABA問(wèn)題,采用雙保險(xiǎn)的CAS技術(shù),將計(jì)算機(jī)能一次操作的存儲(chǔ)區(qū)域分為高地址部分和低地址部分,高地址部分為標(biāo)志位,低地址部分為數(shù)據(jù)位,同時(shí)對(duì)標(biāo)志位和數(shù)據(jù)位進(jìn)行CAS操作,避免ABA問(wèn)題發(fā)生;對(duì)于偽共享問(wèn)題,在頭指針、尾指針和容量三個(gè)變量間使用緩沖行填充方法,避免頭指針、尾指針和容量三個(gè)變量在同一個(gè)緩沖行中,造成偽共享問(wèn)題。
[0029]本實(shí)施例的環(huán)形緩沖區(qū)的中心數(shù)據(jù)結(jié)構(gòu)采用一個(gè)基于定長(zhǎng)數(shù)組(長(zhǎng)度為2的指數(shù)倍,模型中選擇2048)的環(huán)形隊(duì)列。環(huán)形緩沖區(qū)里頭尾指針都是不斷永遠(yuǎn)向前計(jì)數(shù),不斷在環(huán)形緩沖區(qū)中循環(huán)。
[0030]#define MAX_QUEUE_LEN 2048
struct msg_queue_cb {
u32buffer[MAX_QUEUE_LEN];
struct padded—datawritepos;
struct padded—datareadpos;
struct padded—dataqueue_len;
sem—tfull_sem;
sem—tempty—sem;
};
本實(shí)施例偽共享解決辦法是在頭指針、尾指針、容量三個(gè)數(shù)據(jù)變量間使用緩沖行填充方式。CPU會(huì)把數(shù)據(jù)從內(nèi)存加載到高速緩存中,這樣可以獲得更好的性能,高速緩存默認(rèn)大小是64字節(jié)為一個(gè)區(qū)域,CPU機(jī)制限制只能一個(gè)CPU的一個(gè)線(xiàn)程訪(fǎng)問(wèn)(寫(xiě))這個(gè)高速緩存區(qū)。CPU在將主內(nèi)存中數(shù)據(jù)加載到高速緩存時(shí),如果發(fā)現(xiàn)被加載的數(shù)據(jù)不足64字節(jié),那么就會(huì)加載多個(gè)數(shù)據(jù),以填滿(mǎn)自己的64字節(jié),這樣一個(gè)高速緩存中可能加載了兩個(gè)對(duì)象指針,一個(gè)CPU —個(gè)高速緩存,雙核就是兩個(gè)CPU各自一個(gè)高速緩存,那么兩個(gè)高速緩存中各有兩個(gè)對(duì)象指針,都是指向相同的兩個(gè)對(duì)象。因?yàn)橐粋€(gè)CPU只能訪(fǎng)問(wèn)(寫(xiě))自己高速緩存區(qū)中數(shù)據(jù),相當(dāng)于給這個(gè)數(shù)據(jù)加鎖,那么另外一個(gè)CPU同時(shí)訪(fǎng)問(wèn)自己高速緩存中同樣數(shù)據(jù)時(shí)將會(huì)被鎖定不能訪(fǎng)問(wèn)。這就發(fā)生與鎖機(jī)制類(lèi)似的性能陷進(jìn),所以,盡管兩個(gè)線(xiàn)程是在寫(xiě)兩個(gè)不同的字段值,也會(huì)因?yàn)殡p核CPU底層機(jī)制發(fā)生偽裝的共享,并沒(méi)有真正共享,其實(shí)還是排他性的獨(dú)享。解決辦法是填滿(mǎn)高速緩存的64字節(jié),這樣CPU將數(shù)據(jù)加載到高速緩存時(shí),就只能加載一個(gè)了。根據(jù)高速緩存大小的不同可以修改填充內(nèi)容的大小。
【權(quán)利要求】
1.一種無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:儲(chǔ)存消息數(shù)據(jù)的緩沖區(qū)采用環(huán)形數(shù)組結(jié)構(gòu),而不是采用鏈表結(jié)構(gòu),使數(shù)據(jù)存儲(chǔ)在同一片存儲(chǔ)區(qū)域,便于緩存預(yù)讀,同時(shí)避免鏈表節(jié)點(diǎn)每次操作時(shí)所需要申請(qǐng)或釋放內(nèi)存操作,提高效率。
2.根據(jù)權(quán)利要求1所述的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:對(duì)于多生產(chǎn)者單消費(fèi)者模型的并發(fā)控制問(wèn)題,采用CAS和內(nèi)存屏障保證互斥,不使用加鎖的方式,避免鎖的低效帶來(lái)的性能劣化。
3.根據(jù)權(quán)利要求1所述的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:為避免ABA問(wèn)題,采用雙保險(xiǎn)的CAS技術(shù),將計(jì)算機(jī)能一次操作的存儲(chǔ)區(qū)域分為高地址部分和低地址部分,高地址部分為標(biāo)志位,低地址部分為數(shù)據(jù)位,同時(shí)對(duì)標(biāo)志位和數(shù)據(jù)位進(jìn)行CAS操作,避免ABA問(wèn)題發(fā)生。
4.根據(jù)權(quán)利要求1所述的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:對(duì)于偽共享問(wèn)題,在頭指針、尾指針和容量三個(gè)變量間使用緩沖行填充方法,避免頭指針、尾指針和容量三個(gè)變量在同一個(gè)緩沖行中,造成偽共享問(wèn)題。
5.根據(jù)權(quán)利要求1所述的無(wú)鎖并發(fā)消息處理機(jī)制的實(shí)現(xiàn)方法,其特征在于:所述的環(huán)形數(shù)組長(zhǎng)度設(shè)為2的指數(shù)倍,采用“與操作”的位運(yùn)算代替“取余操作”來(lái)獲取數(shù)組下標(biāo),利用計(jì)算機(jī)“與操作”的效率高于“取余操作”的特性來(lái)提高整體效率。
【文檔編號(hào)】G06F9/38GK104077113SQ201410327258
【公開(kāi)日】2014年10月1日 申請(qǐng)日期:2014年7月10日 優(yōu)先權(quán)日:2014年7月10日
【發(fā)明者】袁浩, 曾令將 申請(qǐng)人:中船重工(武漢)凌久電子有限責(zé)任公司