色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

無鎖隊列的潛在優勢

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-09 09:23 ? 次閱讀

無鎖隊列

先大致介紹一下無鎖隊列。無鎖隊列的根本是CAS函數——CompareAndSwap,即比較并交換,函數功能可以用C++函數來說明:

int compare_and_swap (int* reg, int oldval, int newval)
{
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
return old_reg_val;
}

它將reg的值與oldval的值進行對比,若相同則將reg賦新值。注意以上操作是原子操作。大部分語言都有提供CAS支持,不過函數原型可能有些微的不同,許多語言(包括go)中CAS的返回值是標識是否賦值成功的bool值。

無鎖隊列則是以CAS來實現同步的一種隊列,我的具體實現這里就不貼出來了,有點冗長,文末給出了源碼地址。這里僅僅大致給出實現思路,網上關于無鎖隊列的資料很多,這里就不詳細說了。

EnQueue(x) //進隊列改良版
{
q = new record();
q->value = x;
q->next = NULL;

p = tail;
oldp = p
do {
while (p->next != NULL)
p = p->next;
} while( CAS(p.next, NULL, q) != TRUE); //如果沒有把結點鏈在尾上,再試

CAS(tail, oldp, q); //置尾結點
}

DeQueue() //出隊列
{
do{
p = head;
if (p->next == NULL){
return ERR_EMPTY_QUEUE;
}
while( CAS(head, p, p->next) != TRUE );
return p->next->value;
}

自旋鎖

自旋鎖是加鎖失敗時接著循環請求加鎖,直到成功。它的特點是不會釋放CPU,故也沒有互斥鎖那種內核態切換操作,但缺點也很明顯,就是會一直占用CPU,理論上適用于臨界區小、不需要長時間加鎖的場景。 這里只貼鎖的相關代碼,隊列的實現就不貼了:

// 自旋鎖
type spinMutex struct {
mutex int32
}
const locked = 1
const unlocked = 0
func (spin *spinMutex) lock() {
for !atomic.CompareAndSwapInt32(&spin.mutex, unlocked, locked) {}
}
func (spin *spinMutex) unlock() {
atomic.SwapInt32(&spin.mutex, unlocked)
}

互斥鎖

這個沒什么好說的,用的golang自帶的互斥鎖sync.Mutex。

測試

下面將分2種場景進行測試:分別是高并發和低并發。高并發我用4個協程往隊列中push數據,4個協程從隊列中pop數據(雖然不是很高,但足以區分性能,就沒測太高并發了,畢竟測一次等的太久也累);低并發不好模擬,于是我干脆極端點改為無并發——先順序寫,再順序讀。

無并發

大致測試代碼結構如下(刪減了不關鍵的語句):

t1 := time.Now()
for i := 1; i <= dataNum; i++ {
suc := queue.PushBack(i)
}
queue.Disable()

for {
val, enable := queue.PopFront()
if !enable {
break
}
}
fmt.Println("用時:", time.Since(t1))

為了方便對比,我特地還增加了不加鎖的隊列的測試結果。測試結果如下:(左側為dataNum數據量)

圖片

添加圖片注釋,不超過 140 字(可選)

可以看到數據量小的時候性能差別還不明顯,甚至cas還有少許的優勢。但數據量一大就很明顯的看出自旋鎖的效率會高一點,cas次之。不過它們差別都不大。

高并發

這里用4個生產者4個消費者共用一個隊列來模擬高并發。測試代碼結構如下:

func test() {
wgr := sync.WaitGroup{}
wgw := sync.WaitGroup{}
t1 := time.Now()
for i := 0; i < 4; i++ {
wgr.Add(1)
go reader(i*1000000, &wgr)
}
for i := 0; i < 4; i++ {
wgw.Add(1)
go writter(&wgw)
}
wgr.Wait()
queue.Disable()
wgw.Wait()
fmt.Println("用時:", time.Since(t1))
}
func reader(startNum int, wg *sync.WaitGroup) {
for i := 0; i < dataNum; i++ {
suc := queue.PushBack(startNum + i)
for !suc {
suc = queue.PushBack(startNum + i)
}
}
wg.Done()
}
func writter(wg *sync.WaitGroup) {
for {
r, enable := queue.PopFront()
if enable == false {
break
}
if r == defaultVal {
continue
}
}
wg.Done()
}

這種情況下就沒法測試無鎖隊列了,數據都不完整(已驗證)。測試結果如下,左側為讀/寫協程數*dataNum數據量(下面讀/寫協程數為4指總共開了8個協程):

圖片

添加圖片注釋,不超過 140 字(可選)

可以看到cas有巨大的性能優勢,甚至達到了3到5倍的性能差距,說明這個思路還是可行的!(先開始被chan打擊到了)反倒是自旋鎖的性能最差,這個倒有些出乎我的意料,按照我的理解在這種頻繁加鎖解鎖的情況下自旋鎖的性能應該更好才對,若有知情人士望告知。

分析

為了對這幾種鎖的性能特點有更深入的分析,這里還補充了幾組測試,分別用了不同的協程數和數據量進行補充測試:

圖片

添加圖片注釋,不超過 140 字(可選)

可以很明顯的看到一個趨勢——隨著并發度增加,自旋鎖的性能急劇下降,由無并發時的與cas性能幾乎一樣到最后與cas將近7倍的效率差。而mutex和cas情況下,隨著并發度增加,性能影響并不大,下面將前面的測試數據重新組織一下方便對比:

圖片

添加圖片注釋,不超過 140 字(可選)

可以看到總數據量不變的情況下,并發協程數對mutex和cas的影響非常小,基本在波動范圍以內。相較之下自旋鎖就比較慘了。

總結

**根據上面的結果來說的話,當實際競爭特別小的時候,可以考慮用自旋鎖;而并發大的時候,用無鎖隊列這種結構有很大潛在優勢。**之所以說潛在的是因為我也僅僅是簡單的實現某種結構,肯定有考慮不全的地方,我寫這個無鎖例子主要用于測試,也沒打算用于實際場景中。但是我盡量保證了同樣的代碼結構下,最大化各個鎖結構對性能的影響。總的來說,本文測試結果僅作參考,希望能有拋磚引玉的效果。

最后,再附上源碼地址:https://github.com/HandsomeRosin/lockfree

更新:

針對自旋鎖效率低下的問題我仔細想了想,應該是原子操作cas耗時的問題(畢竟在無并發情況下,cas和真正不加鎖還是有很大的性能差距)。于是對自旋鎖的代碼進行了微調,減少了CAS的調用次數:(被注釋掉的是原本的代碼邏輯)

func (spin *spinMutex) lock() {
// for !atomic.CompareAndSwapInt32(&spin.mutex, unlocked, locked) {}
BEGINING:
for spin.mutex != unlocked {}
if !atomic.CompareAndSwapInt32(&spin.mutex, unlocked, locked) {
goto BEGINING
}
}

事實證明,這樣做效率確實提高了約1/4,不過還是改變不了它的大趨勢(與cas和mutex的性能差距依舊巨大),所以就沒更新前面的測試數據了。

不過這也佐證了CAS也是比較耗時的一個操作,平時還是不能肆意使用。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7067

    瀏覽量

    89110
  • 源碼
    +關注

    關注

    8

    文章

    643

    瀏覽量

    29244
  • 函數
    +關注

    關注

    3

    文章

    4333

    瀏覽量

    62691
  • CAS
    CAS
    +關注

    關注

    0

    文章

    34

    瀏覽量

    15213
收藏 人收藏

    評論

    相關推薦

    使用USB進行測量應用的優勢潛在危險

    使用USB進行測量應用的優勢潛在危險 引言:USB用于測試與測量應用的優勢很多,但是在選擇USB
    發表于 05-11 21:11 ?333次閱讀

    《有》/《》/《簽約》/《解鎖》/《越獄》/《激活》專

    《有》/《》/《簽約》/《解鎖》/《越獄》/《激活》專業技術詞解析 在討論區里,大家看到:《有版》,《
    發表于 02-03 11:05 ?956次閱讀

    AWorks軟件設計,郵箱、消息隊列和自旋使用方法

    本文介紹了郵箱、消息隊列和自旋的使用方法。信號量只能用于任務間的同步,不能傳遞更多的信息,為此,AWorks提供了郵箱和消息隊列服務,它們的主要區別在于支持的消息長度不同,在郵箱中,每條消息的長度固定為4字節,而在消息
    的頭像 發表于 06-13 09:13 ?1.3w次閱讀
    AWorks軟件設計,郵箱、消息<b class='flag-5'>隊列</b>和自旋<b class='flag-5'>鎖</b>使用方法

    智能按鍵出現反應或禁止操作的原因坤坤智能告訴你

    智能按鍵出現反應或禁止操作的原因坤坤智能告訴你在日常生活中使用智能時,多多少少會遇到智能熱鍵
    發表于 12-14 14:47 ?1.1w次閱讀

    利用CAS技術實現隊列

    【 導讀 】:本文 主要講解利用CAS技術實現隊列。 關于隊列的實現,網上有很多文章,雖
    的頭像 發表于 01-11 10:52 ?2297次閱讀
    利用CAS技術實現<b class='flag-5'>無</b><b class='flag-5'>鎖</b><b class='flag-5'>隊列</b>

    關于CAS等原子操作介紹 隊列的鏈表實現方法

    在開始說隊列之前,我們需要知道一個很重要的技術就是CAS操作——Compare & Set,或是 Compare & Swap,現在幾乎所有的CPU指令都支持CAS的原子操作
    的頭像 發表于 05-18 09:12 ?3439次閱讀
    關于CAS等原子操作介紹 <b class='flag-5'>無</b><b class='flag-5'>鎖</b><b class='flag-5'>隊列</b>的鏈表實現方法

    怎么設計實現一個高并發的環形連續內存緩沖隊列

    隊列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進行刪除操作,而在表的后端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭
    的頭像 發表于 02-15 14:59 ?1356次閱讀
    怎么設計實現一個<b class='flag-5'>無</b><b class='flag-5'>鎖</b>高并發的環形連續內存緩沖<b class='flag-5'>隊列</b>

    發燒友實測 | i.MX8MP 編譯DPDK源碼實現rte_ring隊列進程間通信

    作者|donatello1996來源|電子發燒友題圖|飛凌嵌入式rte_ring是一個用CAS實現的FIFO環形隊列,支持多消費者/生產者同時出入隊列,常用于多線程/多進程之間的通
    的頭像 發表于 01-10 16:29 ?2033次閱讀
    發燒友實測 | i.MX8MP 編譯DPDK源碼實現rte_ring<b class='flag-5'>無</b><b class='flag-5'>鎖</b>環<b class='flag-5'>隊列</b>進程間通信

    源智能的應用前景

    ,但應用前景廣闊。源智能的發展優勢:1.政策支持:近年來,國家大力推進物聯網、大數據、新能源的發展,并且陸續出臺各項產業政策,引導智能行業有序化、高端化發展,
    的頭像 發表于 09-22 10:18 ?1559次閱讀
    <b class='flag-5'>無</b>源智能<b class='flag-5'>鎖</b>的應用前景

    新品上架——源智能把手

    為了迎合市場需求,2022年我司開始著手開發源智能把手。經過幾個月的努力,2022年11月我司正式上架源智能把手源智能把手
    的頭像 發表于 11-11 17:56 ?607次閱讀
    新品上架——<b class='flag-5'>無</b>源智能把手<b class='flag-5'>鎖</b>

    源智能系統之水務消防

    源智能系統之水務消防
    的頭像 發表于 05-22 09:48 ?476次閱讀
    <b class='flag-5'>無</b>源智能<b class='flag-5'>鎖</b>系統之水務消防

    固態電池(SSBs)的潛在優勢

    與用于日常手機和電動汽車的傳統鋰離子電池相比,固態電池(SSBs)具有重要的潛在優勢
    發表于 09-25 09:28 ?709次閱讀
    固態電池(SSBs)的<b class='flag-5'>潛在</b><b class='flag-5'>優勢</b>

    如何實現一個多讀多寫的線程安全的隊列

    在ZMQ隊列的原理與實現一文中,我們已經知道了ypipe可以實現一線程寫一線程讀的隊列
    的頭像 發表于 11-08 15:25 ?1339次閱讀
    如何實現一個多讀多寫的線程安全的<b class='flag-5'>無</b><b class='flag-5'>鎖</b><b class='flag-5'>隊列</b>

    隊列解決的問題

    為什么需要隊列 隊列解決了什么問題?
    的頭像 發表于 11-10 15:33 ?963次閱讀
    <b class='flag-5'>無</b><b class='flag-5'>鎖</b><b class='flag-5'>隊列</b>解決的問題

    CAS如何實現各種的數據結構

    ,可用于在多線程編程中實現不被打斷的數據交換操作,從而避免多線程同時改寫某?數據時由于執行順序不確定性以及中斷的不可預知性產?的數據不一致問題 有了CAS,我們就可以用它來實現各種(lock free)的數據結構 實現原理 該操作通過將內存中的值與指定數據進行比較,
    的頭像 發表于 11-13 15:38 ?825次閱讀
    <b class='flag-5'>無</b><b class='flag-5'>鎖</b>CAS如何實現各種<b class='flag-5'>無</b><b class='flag-5'>鎖</b>的數據結構
    主站蜘蛛池模板: 亚洲精品国偷拍电影自产在线| 欧美午夜精品A片一区二区HD| 亚洲spank男男实践网站| 久久re视频这里精品09免费| 哺乳期妇女挤奶水36d| 亚洲一区精品在线| 色婷婷国产麻豆AV| 嫩小xxxxbbbb| 久久艹伊人| 国产精品自产拍在线观看网站| 97在线播放视频| 一本二卡三卡四卡乱码麻豆| 色欲无码国产喷水AV精品| 蜜臀AV久久国产午夜福利软件 | 亚洲国产高清在线| 日本真人啪啪试看30秒| 老男人粗大猛| 九九这里有精品| 国产亚洲精品免费视频| 打扑克床上视频不用下载免费观看| 最新精品学生国产自在现拍| 高清大胆欧美videossexo| 综合亚洲桃色第一影院| 亚洲免费人成在线视频观看| 三级中国免费的| 欧美日韩在线成人看片a| 久久天天躁狠狠躁夜夜呲| 黑色丝袜美腿美女被躁翻了| 国产高清免费观看| 钉钉女老师| 超碰国产视频免费播放| a国产成人免费视频| 999久久精品国产| 91亚洲精品| 92国产精品午夜免费福利视频| 中文字幕亚洲无限码| 尹人综合网| 中文成人在线视频| 在线免费观看国产视频| 在线观看成人3d动漫入口| 一区二区三区内射美女毛片|