Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
C++で末尾再帰を最適化したい / Cpp-tail-recursion-elimination
Search
Shinonome517
July 13, 2022
Programming
0
880
C++で末尾再帰を最適化したい / Cpp-tail-recursion-elimination
07/13 RICORA Programming TeamのLTで用いた発表スライド
Shinonome517
July 13, 2022
Tweet
Share
More Decks by Shinonome517
See All by Shinonome517
Slide for lt-20220511
shinonome517
0
830
Other Decks in Programming
See All in Programming
AIと一緒にレガシーに向き合ってみた
nyafunta9858
0
230
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
6
1.8k
Implementation Patterns
denyspoltorak
0
280
【卒業研究】会話ログ分析によるユーザーごとの関心に応じた話題提案手法
momok47
0
200
CSC307 Lecture 05
javiergs
PRO
0
500
IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC
gam0022
1
300
KIKI_MBSD Cybersecurity Challenges 2025
ikema
0
1.3k
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
3.9k
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
230
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.5k
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
Featured
See All Featured
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
0
1.9k
Color Theory Basics | Prateek | Gurzu
gurzu
0
200
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
430
Abbi's Birthday
coloredviolet
1
4.7k
How to build a perfect <img>
jonoalderson
1
4.9k
Test your architecture with Archunit
thirion
1
2.1k
Thoughts on Productivity
jonyablonski
74
5k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.7k
Done Done
chrislema
186
16k
First, design no harm
axbom
PRO
2
1.1k
Transcript
C++ で末尾再帰を最適化 したい B3 Shinonome 2022/06/03 © 2022 @Shinonome517Stu 1
結論 末尾再帰とは、関数のreturn 処理直前のみで再帰呼び出しを行う再 帰である C++(GNU GCC) では-O2 レベルの最適化を行うことで末尾再帰最適 化がなされる 2022/06/03
© 2022 @Shinonome517Stu 2
動機 C++ でも再帰を書きてぇなぁ・・・ 2022/06/03 © 2022 @Shinonome517Stu 3
末尾再帰最適化とは 以下三つを理解している必要がある 関数呼び出しの仕組み 再帰呼び出し 末尾関数呼び出し 2022/06/03 © 2022 @Shinonome517Stu 4
関数呼び出しの仕組み サブルーチンを呼ぶ際、次の命令が格納されているアドレスをスタッ クに積む(PUSH) メインルーチンに戻る際、次の命令が格納されているアドレスをスタ ックから読み取る(POP) → スタック領域が消費される 2022/06/03 © 2022
@Shinonome517Stu 5
出典 IPA :セキュアプログラミング講座 2022/06/03 © 2022 @Shinonome517Stu 6
再帰呼び出し 関数内部で、自分自身を呼び出す関数呼び出しのこと ベースケースに到達するまで、関数を呼び出し続ける → スタックオーバーフローの危険がある 2022/06/03 © 2022 @Shinonome517Stu 7
再帰呼び出し int fib(int n){ if(n == 0){ return 0; }
else{ return fib(n-1) + fib(n-2); } } 2022/06/03 © 2022 @Shinonome517Stu 8
末尾関数呼び出し return 処理の直前に関数を呼び出しをしている、関数呼び出しのこと 下の例では特に再帰呼び出しでもあるので、末尾再帰呼び出しになっ ている 2022/06/03 © 2022 @Shinonome517Stu 9
末尾関数呼び出し int sigma(int n, int ans){ if(n <= 0){ return
ans; } else{ return sigma(n - 1, ans + n); } } 2022/06/03 © 2022 @Shinonome517Stu 10
末尾再帰最適化 通常の再帰呼び出しでは、スタック領域を使い果たしてしまう場合が ある → 末尾再帰の場合に限って、ただのジャンプ命令にすることができる → 末尾再帰最適化 2022/06/03 © 2022
@Shinonome517Stu 11
C++ で末尾再帰を最適化する 和を求める関数を末尾再帰で実装 k k=1 ∑ n 2022/06/03 ©
2022 @Shinonome517Stu 12
ソースコード #include <iostream> #include <cstdint> using namespace std; int64_t sigma(int64_t
n, int64_t ans){ if(n <= 0) return ans; else return sigma(n - 1, ans + n); } int main(){ cout << "sigma(100): " << sigma(100, 0) << endl; cout << "sigma(10000000): " << (int64_t)sigma(10000000, 0) << endl; } 2022/06/03 © 2022 @Shinonome517Stu 13
コンパイル gdb を用いるので-g オプションをつける 以下3 パターンのコンパイルを試す 2022/06/03 © 2022 @Shinonome517Stu
14
最適化オプションなし g++ -g -Wall sigma-rec.cpp -o no-opt.out O1 最適化オプション g++
-g -Wall -O1 sigma-rec.cpp -o opt.out O2 最適化オプション g++ -g -Wall -O2 sigma-rec.cpp -o opt2.out 2022/06/03 © 2022 @Shinonome517Stu 15
実行結果 上から順に「最適化オプションなし」, 「O1 最適化オプション」, 「O2 最適化オプション」の実行結果 →O2 最適化オプションを付した実行ファイルのみ、正しく実行できて いる 2022/06/03
© 2022 @Shinonome517Stu 16
実行結果 2022/06/03 © 2022 @Shinonome517Stu 17
gdb 解析結果 ターミナルで gdb ./"file name" (gdb) disass sigma でsigma
関数を逆アセンブルした 2022/06/03 © 2022 @Shinonome517Stu 18
最適化オプションなし 2022/06/03 © 2022 @Shinonome517Stu 19
O1 最適化オプション 余分な処理は消されているようだが、call 命令(関数呼び出し)は行 われている 2022/06/03 © 2022 @Shinonome517Stu 20
O2 最適化オプション call 命令(関数呼び出し命令)が消えている 2022/06/03 © 2022 @Shinonome517Stu 21
感想 最適化処理すげー 末尾再帰最適化を行える環境では、積極的に末尾再帰を利用したい 2022/06/03 © 2022 @Shinonome517Stu 22
参考資料 関数呼び出しの仕組み IPA セキュア・プログラミング講座 CodeZine インラインアセンブラで学ぶアセンブリ言語 第3 回 GNU g++
最適化オプション 2022/06/03 © 2022 @Shinonome517Stu 23
ご清聴ありがとうございました 2022/06/03 © 2022 @Shinonome517Stu 24
おまけ 処理系が違えば、最適化の方法も異なる 以下はClang(Apple) でコンパイルされたsigma 関数を逆アセンブルし た結果 2022/06/03 © 2022 @Shinonome517Stu
25
最適化オプションなし 2022/06/03 © 2022 @Shinonome517Stu 26
O1 最適化オプション 2022/06/03 © 2022 @Shinonome517Stu 27
O2 最適化オプション 2022/06/03 © 2022 @Shinonome517Stu 28