<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > x86和arm架構原子操作的區別

x86和arm架構原子操作的區別

作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò ) 收藏
x86arm原子操作上有些差別,下面一代碼的形式來(lái)說(shuō)明區別:
首先比較單核:
由于x86是CISC指令集,允許在一條指令里進(jìn)行兩次內存操作,所以對i++,i__這些操作在單核條件下是原子,當然必須得是顯示使用addl r,%1這種,就可在一條指令里完成讀,寫(xiě)操作。
而arm屬于RISC指令集,在一次指令執行期間只能有一次內存操作,所以像i++,i--這些需要先讀取內存值然后賦值的操作,在arm架構下沒(méi)法一條指令完成,所以就不滿(mǎn)足原子操作,這時(shí)怎樣實(shí)現原子操作呢:
我們通過(guò)代碼來(lái)看;
對于atomic_add
x86的實(shí)現很簡(jiǎn)單:

static__inline__voidatomic_add(inti,atomic_t*v)
{
__asm____volatile__(
LOCK"addl %1,%0"
:"=m"(v->counter)
:"ir"(i),"m"(v->counter));
}

本文引用地址:http://dyxdggzs.com/article/201611/317840.htm

單核情況下LOCK是空。
下面再看下atomic_add_and_test:

static__inline__inthal_atomic_add_and_test(inti,emcos_atomic_t*v)
{
unsignedcharc;

__asm____volatile__(
LOCK"addl %2,%0; sete %1"
:"=m"(v->val),"=qm"(c)
:"ir"(i),"m"(v->val):"memory");
returnc;
}


可能大家會(huì )想,這個(gè)有兩條指令了,能是原子的嗎?肯定是,為什么是呢?
大家要注意sete %1這個(gè)是條件指令,而這個(gè)條件(cflags)是進(jìn)程相關(guān)的,即使當進(jìn)程執行完add1 %2,%0,這時(shí)發(fā)生中斷,切換到另外一個(gè)進(jìn)程,當回來(lái)的時(shí)候cflags還是進(jìn)程的,和沒(méi)切換的情形一樣,所以是原子。
而對于arm這需要更多工作:

#defineatomic_add(i,v)(void)atomic_add_return(i,v)

staticinlineintatomic_add_return(inti,atomic_t*v)
{
unsignedlongflags;
intval;

local_irq_save(flags);
val=v->counter;
v->counter=val+=i;
local_irq_restore(flags);

returnval;
}


上面可以看出是通過(guò)關(guān)中斷來(lái)實(shí)現的,為什么要關(guān)中斷來(lái)實(shí)現原子操作:
分析下:
arm對于i++會(huì )生成如下代碼:
1ldr r0,=i
2mov [r0],r1 //這個(gè)讀內存操作
3inc r1 //如果在這個(gè)時(shí)候發(fā)生中斷,然后在中斷處理程序中也執行i++操作就不是原子操作
4mov r1,[r0]//這個(gè)寫(xiě)內存操作
假設I=0。如果進(jìn)程1執行i++,執行到3時(shí)被中斷打斷,然后中斷中也執行了i++,當兩個(gè)i++執行完了,i=1,而不是我們所要的2,這就是非原子操作的結果。
怎么解決,就是說(shuō)2-4這段代碼要么不執行,要么執行完才能保證原子,這個(gè)在單核上通過(guò)關(guān)中斷就可以實(shí)現,這也是上面關(guān)中斷的原因。

2.多核情況;
x86架構下:
單指令也不是原子操作了,比如addl r,%1這種有兩次內存操作的也不是原子操作,有可能在執行下一次內存操作的時(shí)候,另一個(gè)核心也讀取了這個(gè)內存,也會(huì )造成兩次i++操作為1的錯誤結果。
解決方法是家LOCK標識,這個(gè)標識的作用是在一條指令執行時(shí),鎖住總線(xiàn),其他核心沒(méi)法讀取,從而得到了原子操作。
arm架構下:
arm只有v6系列后的才有多核,也才有專(zhuān)門(mén)的內存原子操作機制就是ldrex,strex指令。
其源碼如下:

staticinlineintatomic_add_return(inti,atomic_t*v)
{
unsignedlongtmp;
intresult;

__asm____volatile__("@ atomic_add_returnn"
"1: ldrex %0, [%2]n"
" add %0, %0, %3n"
" strex %1, %0, [%2]n"
" teq %1, #0n"
" bne 1b"
:"=&r"(result),"=&r"(tmp)
:"r"(&v->counter),"Ir"(i)
:"cc");

returnresult;
}




關(guān)鍵詞: x86arm架構原子操

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>