• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            關(guān)于單CPU,多CPU上的原子操作  轉(zhuǎn)自http://software.intel.com/zh-cn/blogs/2010/01/14/cpucpu/?cid=sw:prccsdn956

                所謂原子操作,就是"不可中斷的一個(gè)或一系列操作" 。

            硬件級(jí)的原子操作:
                在單處理器系統(tǒng)(UniProcessor)中,能夠在單條指令中完成的操作都可以認(rèn)為是" 原子操作",因?yàn)橹袛嘀荒馨l(fā)生于指令之間。這也是某些CPU指令系統(tǒng)中引入了test_and_set、test_and_clear等指令用于臨界資源互斥的原因。

                在對(duì)稱(chēng)多處理器(Symmetric Multi-Processor)結(jié)構(gòu)中就不同了,由于系統(tǒng)中有多個(gè)處理器在獨(dú)立地運(yùn)行,即使能在單條指令中完成的操作也有可能受到干擾。

                在x86 平臺(tái)上,CPU提供了在指令執(zhí)行期間對(duì)總線(xiàn)加鎖的手段。CPU芯片上有一條引線(xiàn)#HLOCK pin,如果匯編語(yǔ)言的程序中在一條指令前面加上前綴"LOCK",經(jīng)過(guò)匯編以后的機(jī)器代碼就使CPU在執(zhí)行這條指令的時(shí)候把#HLOCK pin的電位拉低,持續(xù)到這條指令結(jié)束時(shí)放開(kāi),從而把總線(xiàn)鎖住,這樣同一總線(xiàn)上別的CPU就暫時(shí)不能通過(guò)總線(xiàn)訪(fǎng)問(wèn)內(nèi)存了,保證了這條指令在多處理器環(huán)境中 的原子性。
            軟件級(jí)的原子操作:
                軟件級(jí)的原子操作實(shí)現(xiàn)依賴(lài)于硬件原子操作的支持。
                對(duì)于linux而言,內(nèi)核提供了兩組原子操作接口:一組是針對(duì)整數(shù)進(jìn)行操作;另一組是針對(duì)單獨(dú)的位進(jìn)行操作。
            2.1. 原子整數(shù)操作
                針對(duì)整數(shù)的原子操作只能對(duì)atomic_t類(lèi)型的數(shù)據(jù)處理。這里沒(méi)有使用C語(yǔ)言的int類(lèi)型,主要是因?yàn)椋?/p>

                1) 讓原子函數(shù)只接受atomic_t類(lèi)型操作數(shù),可以確保原子操作只與這種特殊類(lèi)型數(shù)據(jù)一起使用

                2) 使用atomic_t類(lèi)型確保編譯器不對(duì)相應(yīng)的值進(jìn)行訪(fǎng)問(wèn)優(yōu)化

                3) 使用atomic_t類(lèi)型可以屏蔽不同體系結(jié)構(gòu)上的數(shù)據(jù)類(lèi)型的差異。盡管Linux支持的所有機(jī)器上的整型數(shù)據(jù)都是32位,但是使用atomic_t的代 碼只能將該類(lèi)型的數(shù)據(jù)當(dāng)作24位來(lái)使用。這個(gè)限制完全是因?yàn)樵赟PARC體系結(jié)構(gòu)上,原子操作的實(shí)現(xiàn)不同于其它體系結(jié)構(gòu):32位int類(lèi)型的低8位嵌入了 一個(gè)鎖,因?yàn)镾PARC體系結(jié)構(gòu)對(duì)原子操作缺乏指令級(jí)的支持,所以只能利用該鎖來(lái)避免對(duì)原子類(lèi)型數(shù)據(jù)的并發(fā)訪(fǎng)問(wèn)。

                原子整數(shù)操作最常見(jiàn)的用途就是實(shí)現(xiàn)計(jì)數(shù)器。原子整數(shù)操作列表在中定義。原子操作通常是內(nèi)斂函數(shù),往往通過(guò)內(nèi)嵌匯編指令來(lái)實(shí)現(xiàn)。如果某個(gè)函數(shù)本來(lái)就是原子的,那么它往往會(huì)被定義成一個(gè)宏。

            在編寫(xiě)內(nèi)核時(shí),操作也簡(jiǎn)單:

                atomic_t use_cnt;

                atomic_set(&use_cnt, 2);

                atomic_add(4, &use_cnt);

                atomic_inc(use_cnt);

            2.2. 原子性與順序性

                原子性確保指令執(zhí)行期間不被打斷,要么全部執(zhí)行,要么根本不執(zhí)行。而順序性確保即使兩條或多條指令出現(xiàn)在獨(dú)立的執(zhí)行線(xiàn)程中,甚至獨(dú)立的處理器上,它們本該執(zhí)行的順序依然要保持。

            2.3. 原子位操作

                原子位操作定義在文件中。令人感到奇怪的是位操作函數(shù)是對(duì)普通的內(nèi)存地址進(jìn)行操作的。原子位操作在多數(shù)情況下是對(duì)一個(gè)字長(zhǎng)的內(nèi)存訪(fǎng)問(wèn),因而位號(hào)該位于0-31之間(在64位機(jī)器上是0-63之間),但是對(duì)位號(hào)的范圍沒(méi)有限制。

            編寫(xiě)內(nèi)核代碼,只要把指向了你希望的數(shù)據(jù)的指針給操作函數(shù),就可以進(jìn)行位操作了:

                unsigned long word = 0;

                set_bit(0, &word); /*第0位被設(shè)置*/

                set_bit(1, &word); /*第1位被設(shè)置*/

                clear_bit(1, &word); /*第1位被清空*/

                change_bit(0, &word); /*翻轉(zhuǎn)第0位*/

            為什么關(guān)注原子操作?
                1)在確認(rèn)一個(gè)操作是原子的情況下,多線(xiàn)程環(huán)境里面,我們可以避免僅僅為保護(hù)這個(gè)操作在外圍加上性能開(kāi)銷(xiāo)昂貴的鎖。
                2)借助于原子操作,我們可以實(shí)現(xiàn)互斥鎖。
                3)借助于互斥鎖,我們可以把一些列操作變?yōu)樵硬僮鳌?/p>

            GNU C中x++是原子操作嗎?
                答案不是。x++由3條指令完成。x++在單CPU下不是原子操作。
                對(duì)應(yīng)3條匯編指令
                movl x, %eax
                addl $1, %eax
                movl %eax, x
                在vc2005下對(duì)應(yīng)
                ++x;
                004232FA mov eax,dword ptr [x]
                004232FD add eax,1
                00423300 mov dword ptr [x],eax
                仍然是3條指令。
                所以++x,x++等都不是原子操作。因其步驟包括了從內(nèi)存中取x值放入寄存器,加寄存器,把值寫(xiě)入內(nèi)存三個(gè)指令。

            如何實(shí)現(xiàn)x++的原子性?
                在單處理器上,如果執(zhí)行x++時(shí),禁止多線(xiàn)程調(diào)度,就可以實(shí)現(xiàn)原子。因?yàn)閱翁幚淼亩嗑€(xiàn)程并發(fā)是偽并發(fā)。
                在多處理器上,需要借助cpu提供的Lock功能。鎖總線(xiàn)。讀取內(nèi)存值,修改,寫(xiě)回內(nèi)存三步期間禁止別的CPU訪(fǎng)問(wèn)總線(xiàn)。同時(shí)我估計(jì)使用Lock指令鎖總線(xiàn)的時(shí)候,OS也不會(huì)把當(dāng)前線(xiàn)程調(diào)度走了。要是調(diào)走了,那就麻煩了。

                在多處理器系統(tǒng)中存在潛在問(wèn)題的原因是:
                不使用LOCK指令前綴鎖定總線(xiàn)的話(huà),在一次內(nèi)存訪(fǎng)問(wèn)周期中有可能其他處理器會(huì)產(chǎn)生異常或中斷,而在異常處理中有可能會(huì)修改尚未寫(xiě)入的地址,這樣當(dāng)INC操作完成后會(huì)產(chǎn)生無(wú)效數(shù)據(jù)(覆蓋了前面的修改)。

                spinlock 用于CPU同步, 它的實(shí)現(xiàn)是基于CPU鎖定數(shù)據(jù)總線(xiàn)的指令.
                當(dāng)某個(gè)CPU鎖住數(shù)據(jù)總線(xiàn)后, 它讀一個(gè)內(nèi)存單元(spinlock_t)來(lái)判斷這個(gè)spinlock 是否已經(jīng)被別的CPU鎖住. 如果否, 它寫(xiě)進(jìn)一個(gè)特定值, 表示鎖定成功, 然后返回. 如果是, 它會(huì)重復(fù)以上操作直到成功, 或者spin次數(shù)超過(guò)一個(gè)設(shè)定值. 鎖定數(shù)據(jù)總線(xiàn)的指令只能保證一個(gè)機(jī)器指令內(nèi), CPU獨(dú)占數(shù)據(jù)總線(xiàn).
                單CPU當(dāng)然能用spinlock, 但實(shí)現(xiàn)上無(wú)需鎖定數(shù)據(jù)總線(xiàn).

                spinlock在鎖定的時(shí)候,如果不成功,不會(huì)睡眠,會(huì)持續(xù)的嘗試,單cpu的時(shí)候spinlock會(huì)讓其它process動(dòng)不了.

            from:
            http://blog.csdn.net/microtong/archive/2010/01/20/5211750.aspx


            posted on 2010-04-03 21:05 chatler 閱讀(1312) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C++_BASIS
            <2008年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(10)

            隨筆分類(lèi)(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺(jué)這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺(jué)得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            精品99久久aaa一级毛片| 麻豆久久久9性大片| 久久成人影院精品777| 四虎国产精品免费久久5151 | 久久国产免费直播| 久久久久国产精品人妻| 曰曰摸天天摸人人看久久久| 亚洲精品乱码久久久久久蜜桃 | 国产精品99精品久久免费| 久久久久九国产精品| 99久久无色码中文字幕| 国产精品成人久久久| 韩国三级中文字幕hd久久精品| 亚洲精品国精品久久99热一| 久久久久国产视频电影| 久久久久夜夜夜精品国产| 亚洲AV无一区二区三区久久| 无码精品久久一区二区三区| 久久免费视频网站| 亚洲午夜久久久久久久久电影网 | 国产精品久久久久久久午夜片| 一本久久a久久精品亚洲| 亚洲综合久久夜AV | 久久久久亚洲AV无码去区首| 日韩精品久久久久久| 久久成人国产精品| 日韩精品久久久久久免费| 97久久国产露脸精品国产| 精品久久久一二三区| 久久这里都是精品| 97精品伊人久久久大香线蕉 | 久久久久亚洲AV无码麻豆| 久久久久se色偷偷亚洲精品av| 久久婷婷是五月综合色狠狠| 午夜精品久久久久久影视777| 亚洲人成无码www久久久| 久久国产精品无| 久久久久精品国产亚洲AV无码| 久久久久高潮综合影院| 久久水蜜桃亚洲av无码精品麻豆 | 国产婷婷成人久久Av免费高清|