跳到主要內容

發表文章

目前顯示的是有「cpu」標籤的文章

Memory Barrier in Lock API

由於現今 CPU 與編譯器俱備各種強大的最佳化機制( speculative execution , ALU/LSU pipelines, cache...),使得程式在執行時,並不像程式設計師在 source code level 看到那樣地循序執行。一般情況下,這不會有問題,因為 CPU 通常只會對"獨立的"指令進行重排,但是當我們是在 multi-core 的情況下,就不是這麼顯而易見了。 今天想談一個 memory barrier 的典型應用,當作是...嗯,為研讀 CPU spec 作點整理。 考慮一個情況,現在我們要設計一組 lock/unlock 的 sync API,作為 multithread 的資源同步機制。在沒有 pthread 或其他 OS system call 可用的情況下,我們要如何實現呢? 底下是一個簡單的作法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 struct L { volatile atomic_t flag ; }; void lock_init ( struct * L ) { L -> flag = 0 ; } void lock ( struct * L ) { while ( 1 ) { // if L->flag == 1, atomic_test_and_set does nothing and return 0 // else set it to 1 and return 1 if ( atomic_test_and_set ( L -> flag , 1 )) { break ; ...

Side Effects of Pipeline

這幾天跟同事在實作 IC 的 ROM code 時遇到一個難纏的問題,後來發現與 ARM 的 pipeline 機制有關係,問題是這樣的,看看以下的程式碼(實際上作了什麼事不重要,主要在流程): int  SDRM_BN_Cmp ( SDRM_BIG_NUM  * BN_Src1, SDRM_BIG_NUM  * BN_Src2 ) { effecda8 :        e92d4008        push     { r3, lr } effecdac :        e1a02000        mov     r2, r0 effecdb0 :        e1a0e001        mov     lr, r1          if   ( BN_Src1 - >Length > =  BN_Src2 - >Length )   { effecdb4 :        e5903004        ldr     r3,  [ r0,  #4] effecdb8 :        e591c004        ldr     ip,  [ r1,  #4] effecdbc :        e153000c        cmp     r3, ip effecdc0 :      ...