2013-06-29 34 views
3

我試圖以正確的方式優化此代碼。我的意思是正確的是...我會想象有一種通用的方法來執行這些優化,以便如果其他人查看代碼,他們將能夠刪除優化。對於可讀性代碼優化SPARC彙編中的循環

C採樣...

int a = 1; // mapped to %l0 
int b = 5; // mapped to %l1 
int c = 0; // mapped to %l2 
int d;  // mapped to %l3 

while(a < b) { 
    c += a * b; 
    ++a; 
} 

d = c * b; 

SPARC集版本......

mov %g0, %l2 

    cmp %l0, %l1 
    bge END_LOOP 
    nop 

LOOP: 
    mov %l0, %o0 
    call .mul 
    mov %l1, %o1  ! Fill delay slot with second argument 
    add %l2, %o0, %l2 
    inc %l0 

    cmp %l0, %l1 
    bl  LOOP 
    nop 

END_LOOP: 
    mov %l2, %o0 
    call .mul   ! Fill delay sot with second argument 
    mov %l1, %o1 

    mov %o0, %l3 

我可以優化第一部分(不知道是否正確),但我不知道如何優化第二部分。

mov %g0, %l2 

    cmp %l0, %l1 
    bge,a END_LOOP  ! Annul branch to execute if branch is taken 
    mov %l2, %o0  ! Instruction at target 

LOOP: 
    mov %l0, %o0 
    call .mul 
    mov %l1, %o1  ! Fill delay slot with second argument 
    add %l2, %o0, %l2 
    inc %l0 

    cmp %l0, %l1 
    bl  LOOP 
    nop 

    mov %l2, %o0  ! Move the instruction to above the target 

END_LOOP: 
    call .mul   ! Fill delay sot with second argument 
    mov %l1, %o1 

    mov %o0, %l3 

任何有關如何執行這些優化的幫助將非常感激。

+0

如果您的目標是SPARC v8或更高版本,則可以使用'SMUL'指令而不是調用'.mul'系統庫例程。 – Michael

+0

我可能應該補充一點。這是一個較舊的32位SPARC機器。 – logbaseinfinity

回答

3

一般而言,您的方法是正確的。假設您沒有數據依賴性或緊隨目標之後傳輸控制指令,則通常可以遵循以下約定。

你這樣做,可能沒有意識到:

轉到分支的目標,指令複製到延遲槽和廢止的分支。如您所述,您取消分支以防止在未採取分支時執行該指令。然後將指令移動到標籤上方的目標處。

在你的代碼,按照上面的步驟,你會做以下幾點:

我刪除了你的意見,所以你可以明確地看到我改變。

mov %g0, %l2 

    cmp %l0, %l1 
    bge,a END_LOOP 
    mov %l2, %o0 

    mov %l0, %o0  ! 3. Move the instruction formerly after the loop 
         ! above the label 
LOOP: 
    [ mov %l0, %o0 ] ! Instruction was here 

    call .mul 
    mov %l1, %o1 
    add %l2, %o0, %l2 
    inc %l0 

    cmp %l0, %l1 
    bl,a LOOP   ! 1. Go to the target and copy that instruction into 
         ! they delay slot. 
         ! 2. Annul the branch 
    mov %l0, %o0  ! Instruction formerly after LOOP: 

    mov %l2, %o0 

END_LOOP: 
    call .mul 
    mov %l1, %o1 

    mov %o0, %l3 

如果仔細檢查代碼,您會發現該邏輯仍然存在,並且有系統的方法來展開優化。

無論您是否進入循環,您的代碼仍然會正確執行循環後面的代碼。

這是優化代碼的一般方法,與編譯器所做的相似。關鍵是始終確保數據依賴性不存在。