經(jīng)由FCC同學(xué)提醒,我才發(fā)現(xiàn),之前的兩篇用volatile的無鎖通信,確實(shí)是敗在了優(yōu)化上了。編譯器和CPU硬件會無情的擊毀我們認(rèn)為的執(zhí)行順序。
這篇(0)就是否定掉前兩篇,然后在未來的(3)和(4)里面,將用cas等原語來重新設(shè)計這個無鎖的通信。
關(guān)于編譯器的優(yōu)化,我猜是為了CPU的U/V流水線來做的。它讓狀態(tài)的修改操作,有可能在操作之前就發(fā)生了,從而直接顛覆了整個方法。
另外shbooom所說的,兩個原子操作的問題。可能是少打了一個不字。
我說的原子操作,是在最終操作上來理解的,或者稱為內(nèi)部因果關(guān)聯(lián)上。就是說,對狀態(tài)賦值前的取地址操作,都不算作賦值操作的一部分。同樣的對狀態(tài)進(jìn)行檢查的時候的取地址操作,也不算作檢查的一部分。因?yàn)樗麄兓ゲ挥绊憽W罱K影響檢查狀態(tài)的,只有寫內(nèi)存位置的那一個操作。在這之間出現(xiàn)的執(zhí)行穿插,最多會導(dǎo)致本次檢查無法命中,但下次檢查就一定會命中。
[Barrier]
在多篇文章中,我找到了解決辦法。可以通過Barrier結(jié)束掉之前的所有讀寫操作,從而讓設(shè)置狀態(tài)這個操作的寫操作不會被優(yōu)化到實(shí)際任務(wù)操作的中間或者前面去。
在VC中,有_ReadBarrier _WriteBarrier 和 _ReadWriteBarrier的特殊指令,可以將之前的所有對內(nèi)存的讀和寫或者讀寫的優(yōu)化限制到Barrier之前,從而不會把后面的操作優(yōu)化到前面去。
在其他的編譯器中,應(yīng)該也有相應(yīng)的東西來保障執(zhí)行順序。
不過我還沒測試過這個對性能帶來的影響。希望不要太大。