ビットシフト演算が遅い・・・? Part2
// ord.s .L5: cmpl $10000000, -8(%ebp) jle .L8 jmp .L6 .L8: call rand movl %eax, -12(%ebp) cmpl $0, -12(%ebp) jns .L9 addl $127, -12(%ebp) .L9: movl -12(%ebp), %eax sarl $7, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax sall $3, %eax movl %eax, -4(%ebp) leal -8(%ebp), %eax incl (%eax) jmp .L5
// bit.s .L5: cmpl $10000000, -8(%ebp) jle .L8 jmp .L6 .L8: call rand movl %eax, -12(%ebp) cmpl $0, -12(%ebp) jns .L9 addl $127, -12(%ebp) .L9: movl -12(%ebp), %eax sarl $7, %eax movl %eax, -4(%ebp) leal -4(%ebp), %eax sall $3, (%eax) leal -8(%ebp), %eax incl (%eax) jmp .L5
// ord.s movl -4(%ebp), %eax sall $3, %eax movl %eax, -4(%ebp)
// bit.s leal -4(%ebp), %eax sall $3, (%eax)
どうやら、この辺りに問題がありそうです。
どちらもビットシフトで計算していました。-O0オプションを付けていたのに・・・。
ord.sでは、スタックの内容をアキュムレータ(eax)に代入してビットシフトしていますが、
bit.sでは、スタックのアドレスをアキュムレータ(eax)に代入してビットシフトしているようです。(推測)
gccが賢すぎたorz
ということで、当該個所を以下のように置き換え、ord.sでは乗算命令を使ってみました。
// ord.s movl -4(%ebp), %eax imul $8, %eax movl %eax, -4(%ebp)
// bit.s movl -4(%ebp), %eax sall $3, %eax movl %eax, -4(%ebp)
それぞれ5回実行した結果。
乗算: 平均 341ミリ秒
ビットシフト: 平均 328.4ミリ秒
となりました。
ちなみに、手元のgcc version 3.3.1 (mingw special 20030804-1)でコンパイルしてみたところ、該当部分は以下のようになりました。
movl %eax, -4(%ebp) movl -4(%ebp), %edx movl %edx, %eax addl %eax, %eax addl %edx, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax shrl %eax movl %eax, -4(%ebp)
ずいぶんとややこしいです。