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
820
Other Decks in Programming
See All in Programming
CSC307 Lecture 03
javiergs
PRO
1
490
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
600
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
SourceGeneratorのススメ
htkym
0
190
Architectural Extensions
denyspoltorak
0
280
Fluid Templating in TYPO3 14
s2b
0
130
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
AIによる高速開発をどう制御するか? ガードレール設置で開発速度と品質を両立させたチームの事例
tonkotsuboy_com
7
2.2k
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
510
LLM Observabilityによる 対話型音声AIアプリケーションの安定運用
gekko0114
2
430
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
190
Featured
See All Featured
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
170
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
89
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
140
Ethics towards AI in product and experience design
skipperchong
2
190
Music & Morning Musume
bryan
47
7.1k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.3k
Design in an AI World
tapps
0
140
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
The untapped power of vector embeddings
frankvandijk
1
1.6k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
92
Utilizing Notion as your number one productivity tool
mfonobong
3
220
Paper Plane
katiecoart
PRO
0
46k
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