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
960
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
C++で末尾再帰を最適化したい / Cpp-tail-recursion-elimination
07/13 RICORA Programming TeamのLTで用いた発表スライド
Shinonome517
July 13, 2022
More Decks by Shinonome517
See All by Shinonome517
Slide for lt-20220511
shinonome517
0
860
Other Decks in Programming
See All in Programming
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
170
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
110
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
280
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
270
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.6k
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
190
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
140
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
320
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
150
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
350
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
540
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
200
Featured
See All Featured
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
620
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3k
Un-Boring Meetings
codingconduct
0
390
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
A better future with KSS
kneath
240
18k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
430
Into the Great Unknown - MozCon
thekraken
41
2.7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
630
Visualization
eitanlees
152
17k
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