割り算 VS 右シフト その4

この記事は割り算 VS 右シフト その3の続きです。

実行環境、検証方法などは、割り算 VS 右シフトを参照してください。

割り算 vs 右シフト(割る2 最適化 リテラル以外)

 割り算 VS 右シフト その3 の結果から、リテラルから2を割った場合、最適化オプションをつけてコンパイルを行うと、割り算と右シフトは実行速度が同じになることが分かった。ではリテラル以外を2で割る場合はどうなるだろうか?そこで、div2.cとrshift2.cを以下のように変更し、検証を行うことにした。

検証に使用するプログラム

商 div2_custom.c
/* header files */
#include <stdio.h>
#include <stdlib.h>

/* main */
int main (int argc, char *argv[]) {
    int val;
    scanf("%d", &val);
    printf("%d\n", val / 2);
    return EXIT_SUCCESS;
}
右シフト rshift2_custom.c
/* header files */
#include <stdio.h>
#include <stdlib.h>

/* main */
int main (int argc, char *argv[]) {
    int val;
    scanf("%d", &val);
    printf("%d\n", val >> 1);
    return EXIT_SUCCESS;
}

 上記の2種類のC言語ソースに-O1 -Sオプションをつけてコンパイルし、アセンブラソースを表示させた。2種類のC言語プログラムから生成されたアセンブラソースには差異が認められた。以下に差異とその付近のソースを示す。

商 div2_custom.s
21        call    scanf
22        movl    -8(%ebp), %edx
23        movl    %edx, %eax
24        shrl    $31, %eax
25        addl    %edx, %eax
26        sarl    %eax
27        movl    %eax, 4(%esp)
28        movl    $.LC1, (%esp)
29        call    printf
右シフト rshift2_custom.s
21        call    scanf
22        movl    -8(%ebp), %eax
23        sarl    %eax
24        movl    %eax, 4(%esp)
25        movl    $.LC1, (%esp)
26        call    printf

最適化オプションをつけずにコンパイルした場合と同じく、rshift2.sよりもdiv2.sのほうが3行分ソース行数が多い。

割り算 vs 右シフト(割る2 最適化 リテラル以外)の結果

 右シフトのほうが速い。

割り算 VS 右シフト まとめに続く