亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 14127 | 回復: 15
打印 上一主題 下一主題

關于 atomic 的話題 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-11-20 21:14 |只看該作者 |倒序瀏覽
這里有一個很重要的概念:boundary (邊界)

常見的 boundary:

★ word boundary(16 位)
★ doubleword boundary(32 位)
★ quadword boundary(64 位)

---------------------------------------------------------------------------------

1、造成這些 boundary 的原因是:data bus width (數(shù)據(jù)線的寬度)

  對于 processor 這里有一個很重要的分界點,以 Pentium 處理器為分界,在 Pentium 之前的 data bus 是 32 位,而 Pentiume 之后的 data bus 有 64 位。

  每 8 bits 分成一組 byte,由信號 BE# 來控制 read/write,被稱為 data path

  所以,Pentiume 之后的 processor 有 8 個 data path(BE0 ~ BE7)

  就是由這些 data path 造成了 多種 boundary,這 8 個 data path 造成了可以有 quadword boundary 的出現(xiàn)

  但是 address bus 還是 32,以及后來的 48 位


2、 data path 是影響 boundary 和 atomic 的最主要的因素,

       而造成 非 atomic 的成因就是:跨 bounday,實際上是跨了 8 data path

   因此:跨了 8 個 data path 就會造成 非 atomic 的情況

   在 Pentium 之后的 processor 只要在不是跨 8 data path,即:quadword boudary 的情況下都能保證是 atomic


3、 何為跨 8 data path ?

BE0# ----> 0
BE1# ----> 1
BE2# ----> 2
BE3# ----> 3
BE4# ----> 4
BE5# ----> 5
BE6# ----> 6
BE7# ----> 7
-------------------------------------------
每個 data path 對應控制 1 個 byte

跨 quadword boudary 產(chǎn)生的情形:
  例如:當從 BE3#(3 data path) read/write 一個 quadword(64位),這時就屬于跨 quadword boudary
  這時,processor 需要做 2 次 read/write 操作,這樣,就不能保證 atomic

又例如:
  從 BE3# (3 data path) read/write  一個 word 操作,不會跨過 8 data path,它的 atomic 得到保證。



4、 另一些很壞的情況是:跨 cache line boundary,甚至是:跨 page boundary

  cache line boundary 是:大多數(shù) processor 的 cache line 是 64 bytes(0 ~ 63 byte),如果一個 read/write 是跨過了 64 bytes 這個邊界的話,若使用 lock 來保證它的 atomic 的話,processor 會先做 fill cache line 動作。

  page bundary 是:以 4K page 為例,同樣若跨了 4K bytes 邊界,processor 會做兩次讀 page




5、 以指令來說明“跨 boundary“

指令: mov eax, dword ptr [5]

  這條指令從 地址 5 開始讀 doubleword 到 eax 寄存器

那么:
  (1) processor 先將 BE5# = 0,BE6# = 0,BE7# = 0,其它置 1,使用 data path 5、6、7 有效,其它 data path 無效,先讀 24 位,放到 eax 的低 24 位

  (2) 接著 processor 再置 BE0# = 0,其它置1,使 data path 0 有效,其它 data path 無效,
   讀 byte 放到 eax 的高 8 位

------------------------------------------------------------
  以這樣來完成 doubleword 的讀,這樣 processor 實際上做了 2 次 read 工作。

  所以,atomic 將不能得到保證。

論壇徽章:
0
2 [報告]
發(fā)表于 2009-11-20 21:21 |只看該作者
不能保證 atomic 的第二個因素是:processor 做 read-modify-write 類交易

典型的如:執(zhí)行 add dword ptr [eax], eax 指令


對于這條指令:

1、processor 是 read 從內(nèi)存 [eax] 一個 dword 放到 temp registers

2、processor 做 add 工作,temp registers 與 eax 相加結果放 temp registers

3、processor 寫內(nèi)存 [eax],從 temp registers

-------------------------------------------------------------

這樣,就是 read-modify-write 操作不能保證 atomic


需要 lock 進行 atomic

論壇徽章:
1
天蝎座
日期:2013-10-23 21:11:03
3 [報告]
發(fā)表于 2009-11-20 21:35 |只看該作者
問幾個問題:
1) 編寫一個程序,對齊是不是由編譯器來操作?
2) Intel手冊中沒有明確說明的指令是不是都不能保證操作的原子性?印象中一條指令會分解成一些微操作序列(可能概念不太準
    確,具體忘了^^),是不是因為有的指令分解為比較復雜的操作序列而不能保證原子性?

謝謝!

論壇徽章:
0
4 [報告]
發(fā)表于 2009-11-20 22:20 |只看該作者
原帖由 openspace 于 2009-11-20 21:35 發(fā)表
問幾個問題:
1) 編寫一個程序,對齊是不是由編譯器來操作?
2) Intel手冊中沒有明確說明的指令是不是都不能保證操作的原子性?印象中一條指令會分解成一些微操作序列(可能概念不太準
    確,具體忘了^^) ...


1) 程序員配合編譯器
2) 對內(nèi)存進行 read-modify-write 操作的指令就不能保證 atomic

   如 add,sub,inc,dec,mul 等指令對內(nèi)存進行 read-modify-write
 一些重要的系統(tǒng)指令,processor 會保證它的原子性

論壇徽章:
1
天蝎座
日期:2013-10-23 21:11:03
5 [報告]
發(fā)表于 2009-11-20 23:26 |只看該作者

回復 #4 mik 的帖子

1)"程序員配合編譯器"
     突然想起GCC里面的一些功能可以影響對齊,比如padding
     這樣是不是可以理解如果僅僅是一般的編碼,而不是用這些編譯器提供的輔助功能的話數(shù)據(jù)可能并沒有對齊?
     還是編譯器會默認進行對齊處理,但是遇到特別指定的話再按照指示處理?因為經(jīng)常討論的sizeof看起來
     都是經(jīng)過對齊處理了的
2)用另一個帖子里的例子
     int a = 1;
     int b = a;  // 這一句在32位機上是否能保證原子性
                     // 直覺上感覺需要    讀a的值、獲取b的地址、寫入新值
                     
謝謝!

論壇徽章:
0
6 [報告]
發(fā)表于 2009-11-20 23:41 |只看該作者
原帖由 openspace 于 2009-11-20 23:26 發(fā)表
2)用另一個帖子里的例子
     int a = 1;
     int b = a;  // 這一句在32位機上是否能保證原子性
                     // 直覺上感覺需要    讀a的值、獲取b的地址、寫入新值 ...


是原子性

論壇徽章:
1
天蝎座
日期:2013-10-23 21:11:03
7 [報告]
發(fā)表于 2009-11-21 00:08 |只看該作者

回復 #6 mik 的帖子

剛測試了3種情況

1

  1. int a = 1;

  2. int main(void)
  3. {
  4.         int b = a;
  5.         return 0;
  6. }
復制代碼

  1.         .file        "test1_atomic.c"
  2. .globl a
  3.         .data
  4.         .align 4
  5.         .type        a, @object
  6.         .size        a, 4
  7. a:
  8.         .long        1
  9.         .text
  10. .globl main
  11.         .type        main, @function
  12. main:
  13.         pushl        %ebp
  14.         movl        %esp, %ebp
  15.         subl        $16, %esp

  16.         movl        a, %eax              // ***
  17.         movl        %eax, -4(%ebp)       // ***

  18.         movl        $0, %eax
  19.         leave
  20.         ret
  21.         .size        main, .-main
  22.         .ident        "GCC: (GNU) 4.4.2 20091027 (Red Hat 4.4.2-7)"
  23.         .section        .note.GNU-stack,"",@progbits
復制代碼


2

  1. int a = 1;
  2. int b = 0;

  3. int main(void)
  4. {
  5.         b = a;
  6.         return 0;
  7. }
復制代碼

  1.         .file        "test2_atomic.c"
  2. .globl a
  3.         .data
  4.         .align 4
  5.         .type        a, @object
  6.         .size        a, 4
  7. a:
  8.         .long        1
  9. .globl b
  10.         .bss
  11.         .align 4
  12.         .type        b, @object
  13.         .size        b, 4
  14. b:
  15.         .zero        4
  16.         .text
  17. .globl main
  18.         .type        main, @function
  19. main:
  20.         pushl        %ebp
  21.         movl        %esp, %ebp

  22.         movl        a, %eax        // ***
  23.         movl        %eax, b        // ***

  24.         movl        $0, %eax
  25.         popl        %ebp
  26.         ret
  27.         .size        main, .-main
  28.         .ident        "GCC: (GNU) 4.4.2 20091027 (Red Hat 4.4.2-7)"
  29.         .section        .note.GNU-stack,"",@progbits
復制代碼


3


  1. int main(void)
  2. {
  3.         int a = 1;
  4.         int b = a;
  5.         return 0;
  6. }
復制代碼

  1.         .file        "test3_atomic.c"
  2.         .text
  3. .globl main
  4.         .type        main, @function
  5. main:
  6.         pushl        %ebp
  7.         movl        %esp, %ebp
  8.         subl        $16, %esp
  9.         movl        $1, -8(%ebp)

  10.         movl        -8(%ebp), %eax    // ***
  11.         movl        %eax, -4(%ebp)    // ***

  12.         movl        $0, %eax
  13.         leave
  14.         ret
  15.         .size        main, .-main
  16.         .ident        "GCC: (GNU) 4.4.2 20091027 (Red Hat 4.4.2-7)"
  17.         .section        .note.GNU-stack,"",@progbits
復制代碼


這樣看b=a對應2條匯編語句,而且是通過mov操作完成的
感覺兩條語句之間是有時間間隔的,這樣CPU也能保證原子性?
而且Intel手冊上說的也僅僅是滿足一些條件的read or write操作可以保證原子性,這里涉及兩個操作read and write,是否能保證原子性未知。

論壇徽章:
0
8 [報告]
發(fā)表于 2009-11-21 00:22 |只看該作者

回復 #7 openspace 的帖子

int b = a;

代碼的目的是令 b = a

(1)   movl        a, %eax                     // atomic
(2)   movl        %eax, -4(%ebp)       // atomic

-------------------------------------------------------------
雖然是2條指令,每條指令都是原子的。

(1) 中 a 已經(jīng) load 到 eax 中,即使讀完后 a  被改變,不會影響 eax
(2) 中 eax 已經(jīng) store 到 -4(%ebp) 中,這個 eax 就是 a 值

>>> 即使 write 后,-4(%ebp) 被改寫,那也是 write 完之后的事。

所以:int b = a;  這條語句是原子的,這樣已經(jīng)足夠了

     即使之后 b 被改寫,但 b =  a 語句來說,是原子的。

論壇徽章:
0
9 [報告]
發(fā)表于 2009-11-21 00:27 |只看該作者
又例如:

b = a;      

----------------------------------------------

如果,編譯器是這樣編譯的話:

movl    a,  -4(%ebp)                           //  a ---> temp
movl    -4(%ebp),  %eax                    //  temp ---> eax
movl   %eax, -8(%ebp)                      //  eax ---> b

--------------------------------------------------------------------

中間,多了一個 memory 讀/寫,這就不能保證其原子性了。

論壇徽章:
1
天蝎座
日期:2013-10-23 21:11:03
10 [報告]
發(fā)表于 2009-11-21 09:33 |只看該作者

回復 #8 mik 的帖子

突然感覺跟版主理解的原子性不一樣
一直考慮的是 事務原子性

明白了
謝謝版主了
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP