2014-11-21 72 views
0

我與時下follwoing試驗:混合組裝和Fortran語言加上並行(OpenMP的)

global func_ 
func_: 
    push rbp 
    mov rbp, rsp 

    mov rax,[rdi] 
    mov rbx,[rsi] 

    cmp rbx,1 
    je done 
    dec rbx 

    mov rsi,1 
loop1: 
    shl rsi, 1 
    dec  rbx 
    jnz  loop1 

    or rax,rsi 
    mov [rdi],rax 

    mov rcx,15 
    mov rax,11 
    movq xmm1,rcx 
    movq xmm0, rax 
    xorpd xmm0, xmm1 

    movq rax, xmm0 
    mov [rdi],rax 


    mov rsp, rbp 
    pop rbp 
    ret 

done: 

    or rax,1 
    mov [rdi],rax 
    mov rsp, rbp 
    pop rbp 
    ret 

代碼到目前爲止並沒有真正有意義,我將需要使用XMM [](128按位操作),這彙編代碼應該被編譯成一個對象,並鏈接到Fortran代碼,我會:

! Compile: 
!gfortran -c testassembly.F90; 
!nasm -f elf64 assembly_func.asm; 
!gfortran -o run testassembly.o assembly_func.o; 
!./run 

a = 10 
b = 4 
call func(a,b) 

到現在爲止一切都非常清楚,現在會發生什麼,如果我對如。 OpenMP平行我的代碼,即:

!$omp do schedule(dynamic,1) 
a = 10 
b = 4 
call func(a,b) 
!$omp end do 

換句話說,彙編中的寄存器是物理存在嗎?或者他們將以某種方式對OpenMP線程本地化?如果他們分享,競爭條件和類似情況如何?

我希望我已經夠清楚了。

+0

實際上,CPU有更多的寄存器,甚至對於串行程序,名稱也不與核心中的一個不同的物理寄存器重合。 – 2014-11-21 08:24:27

回答

3

每個線程都有自己的一組寄存器。在線程在單獨的內核上執行的情況下,這很明顯,因爲每個內核都包含一組完整的寄存器。當多個線程共享相同的物理內核時,用戶可見寄存器的狀態在執行切換到另一個線程時保存,然後在執行切換回原始線程(上下文保存/恢復)時稍後恢復,從而給人一種錯覺,即每個線程都專門在寄存器上運行。

至於這些寄存器的物理存在性,現代x86 CPU在它們的核心中沒有固定單元,稱爲RAX,RBX等。它們從舊的RISC概念借用,而它們擁有大量的寄存器稱爲寄存器文件(實際上,現代x86 CPU基本上都是RISC內核,每個CISC指令被拆分爲一組稱爲微操作核的簡單操作)。通過稱爲寄存器重命名的過程,該文件中的每個寄存器都可以用作RAX。這例如允許獨立指令並行執行,即使它們使用相同的寄存器,例如,

mov [rdi], rax 
xor rax, rax 

在這種情況下,第二指令具有在第一個自rax內容被簡單地被覆蓋沒有數據相關性。但是如果有一個RAX寄存器,那麼在第二條指令使用RAX之前,CPU必須首先完成第一條指令的寫到存儲器階段。通過寄存器重命名,第二條指令只需從文件中寫入另一個寄存器,然後從該文件起RAX。

+0

我最近學到的一件有趣的事情是,在Sandy Bridge xor rax上,rax甚至不使用微操作。寄存器文件有一個零寄存器,rax寄存器被重命名爲。唯一的代價是解碼指令。但這很少是一個問題。 – 2014-11-24 09:22:29

+0

我最初的想法是'mov [rdi],rax; mov rax,[rsi]',但後來我決定用不同的東西替換第二個'mov'。我也不知道零寄存器。 – 2014-11-24 12:59:03

+1

如果你感興趣,我在這裏瞭解到它https://stackoverflow.com/questions/26807285/are-static-static-local-sse-avx-variables-blocking-a-xmm-ymm-register/26808698# 26808698 – 2014-11-24 13:01:32