2013-06-29 36 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 

如果仔细检查代码,您会发现该逻辑仍然存在,并且有系统的方法来展开优化。

无论您是否进入循环,您的代码仍然会正确执行循环后面的代码。

这是优化代码的一般方法,与编译器所做的相似。关键是始终确保数据依赖性不存在。