有什么想法吗?我正在为PPC750使用GCC交叉编译器。在循环中对两个浮点数进行简单的乘法运算并对其进行计时。我声明变量是易变的,以确保没有重要的东西被优化,代码加快了!
我已经检查了两种情况的汇编指令,当然,编译器生成了更多指令,以便在非易失性情况下执行相同的基本工作。 10,000,000次迭代的执行时间从800ms降至300ms!
易失性案件的组装:
0x10eeec stwu r1,-32(r1)
0x10eef0 lis r9,0x1d # 29
0x10eef4 lis r11,0x4080 # 16512
0x10eef8 lfs fr0,-18944(r9)
0x10eefc li r0,0x0 # 0
0x10ef00 lis r9,0x98 # 152
0x10ef04 stfs fr0,8(r1)
0x10ef08 mtspr CTR,r9
0x10ef0c stw r11,12(r1)
0x10ef10 stw r0,16(r1)
0x10ef14 ori r9,r9,0x9680
0x10ef18 mtspr CTR,r9
0x10ef1c lfs fr0,8(r1)
0x10ef20 lfs fr13,12(r1)
0x10ef24 fmuls fr0,fr0,fr13
0x10ef28 stfs fr0,16(r1)
0x10ef2c bc 0x10,0, 0x10ef1c # 0x0010ef1c
0x10ef30 addi r1,r1,0x20 # 32
非易失性案件的组合:
0x10ef04 stwu r1,-48(r1)
0x10ef08 stw r31,44(r1)
0x10ef0c or r31,r1,r1
0x10ef10 lis r9,0x1d # 29
0x10ef14 lfs fr0,-18832(r9)
0x10ef18 stfs fr0,12(r31)
0x10ef1c lis r0,0x4080 # 16512
0x10ef20 stw r0,16(r31)
0x10ef24 li r0,0x0 # 0
0x10ef28 stw r0,20(r31)
0x10ef2c li r0,0x0 # 0
0x10ef30 stw r0,8(r31)
0x10ef34 lwz r0,8(r31)
0x10ef38 lis r9,0x98 # 152
0x10ef3c ori r9,r9,0x967f
0x10ef40 cmpl crf0,0,r0,r9
0x10ef44 bc 0x4,1, 0x10ef4c # 0x0010ef4c
0x10ef48 b 0x10ef6c # 0x0010ef6c
0x10ef4c lfs fr0,12(r31)
0x10ef50 lfs fr13,16(r31)
0x10ef54 fmuls fr0,fr0,fr13
0x10ef58 stfs fr0,20(r31)
0x10ef5c lwz r9,8(r31)
0x10ef60 addi r0,r9,0x1 # 1
0x10ef64 stw r0,8(r31)
0x10ef68 b 0x10ef34 # 0x0010ef34
0x10ef6c lwz r11,0(r1)
0x10ef70 lwz r31,-4(r11)
0x10ef74 or r1,r11,r11
0x10ef78 blr
如果我正确读取它,它会在每次迭代中加载内存中的值,但它似乎在非易失性情况下生成了更多指令。< / p>
这是来源:
void floatTest()
{
unsigned long i;
volatile double d1 = 500.234, d2 = 4.000001, d3=0;
for(i=0; i<10000000; i++)
d3 = d1*d2;
}
答案 0 :(得分:2)
您确定没有更改优化设置吗?
原作看起来未经优化 - 这是循环部分:
0x10ef34 lwz r0,8(r31) //Put 'i' in r0.
0x10ef38 lis r9,0x98 # 152 //Put MSB of 10000000 in r9
0x10ef3c ori r9,r9,0x967f //Put LSB of 10000000 in r9
0x10ef40 cmpl crf0,0,r0,r9 //compare r0 to r9
0x10ef44 bc 0x4,1, 0x10ef4c //branch to loop if r0<r9
0x10ef48 b 0x10ef6c //else branch to end
0x10ef4c lfs fr0,12(r31) //load d1
0x10ef50 lfs fr13,16(r31) //load d2
0x10ef54 fmuls fr0,fr0,fr13 //multiply
0x10ef58 stfs fr0,20(r31) //save d3
0x10ef5c lwz r9,8(r31) //load i into r9
0x10ef60 addi r0,r9,0x1 //add 1
0x10ef64 stw r0,8(r31) //save i
0x10ef68 b 0x10ef34 //go back to top, must reload r9
易失性版本看起来非常优化 - 它重新排列指令,并使用专用计数器寄存器而不是将i
存储在堆栈中:
0x10ef00 lis r9,0x98 # 152 //MSB of 10M
//.. 4 initialization instructions here ..
0x10ef14 ori r9,r9,0x9680 //LSB of 10,000000
0x10ef18 mtspr CTR,r9 // store r9 in Special Purpose CTR register
0x10ef1c lfs fr0,8(r1) // load d1
0x10ef20 lfs fr13,12(r1) // load d2
0x10ef24 fmuls fr0,fr0,fr13 // multiply
0x10ef28 stfs fr0,16(r1) // store result
0x10ef2c bc 0x10,0, 0x10ef1c // decrement counter and branch if not 0.
点击率优化将循环减少到5条指令,而不是原始代码中的14条指令。我认为没有任何理由“挥发”本身就能实现优化。