パスワードを忘れた? アカウント作成
15194757 journal
日記

route127の日記: ふーん、アンタが私のコンパイラー?…まあ、悪くないかな…。 2

日記 by route127

過去ログでgccの末尾再帰最適化に触れられていたので自分の環境で試してみた。

gcc version 4.9.2 (i686-posix-sjlj, built by strawberryperl.com project)

最適化のレベルを変えながらアセンブリを出力してみて関数呼び出しを数えてみると、
階乗は末尾再帰で書かなくとも-O2で関数呼び出しが減っていた。
一方フィボナッチ関数は末尾再帰で書かないと最適化でcall数減少につながらなかった。
そもそも自分で書いた関数がアセンブリになると消えていてGDBで見るとスタックを全然使わなくなっていた。

find "call" fib*.s

---------- FIB.S
        call    fib
        call    fib
        call    __main
        call    atoi
        call    fib
        call    printf
 
---------- FIB_O2.S
        call    fib
        call    __main
        call    atoi
        call    fib
 
---------- FIB_TC.S
        call    fib
        call    __main
        call    atoi
        call    fib
        call    printf
 
---------- FIB_TC_O2.S
        call    __main
        call    atoi

偶奇判定の相互再帰関数(与えられた引数から1ひいて偶数判定/奇数判定するevenpとoddpの組)についても試したがあまり最適化が利いてなかった。
たらいまわし関数についても試したが最適化でかえってcallが大幅に増えていた。
コンパイラが何を考えているのか良く分からん。

また、-O2の代わりに-foptimize-sibling-calls(gcc 2.95~)を指定してみたが関数呼び出しの回数は-O2のように減らなかった。

siblingといえば表のストーリ一覧でazureスレの下に渋谷区の話があって蒼歴史を思い出した。

  • by Anonymous Coward on 2021年02月12日 11時09分 (#3976507)

    末尾再帰で書いたらとか、書かなかったらとか、スタックがどうとか、コンパイラの最適化がどうとか、
    そういうしょうもない方向から理解しようとするから、いつも微妙にズレた中途半端な理解で終わるんだよ。
    gcc 4.9.2なんていう遺物を持ち出してみたり、意味もなく逆アセしてわかったふりしなくていいから、
    コンパイラの最適化のように曖昧なものでなく、luaやschemeのように言語仕様上要求してくるプログラム言語の実装部分を読め。
    すると lua -e 'local x=0; for i=1,1e9 do x=x+i end; print(x)' のような、
    末尾再帰関係ない単なるループでさえ何故あれほど早くこなせるのかも同時に理解できるやろ。
    luajitなんざCの同等コード越えてくるレベル。

    ここに返信
    • by Anonymous Coward

      Cのプログラムを題材にメモリ管理の実習をしているときに、それ Rustつかえば大丈夫とか言われたような的外れ具合

      # 日記のほうも callの数数えてどう評価したいのかよくわからないけどまあ独り言だし?

typodupeerror

目玉の数さえ十分あれば、どんなバグも深刻ではない -- Eric Raymond

読み込み中...