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
870
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
ThorVG Viewer In VS Code
nors
0
750
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
260
高速開発のためのコード整理術
sutetotanuki
1
340
開発者から情シスまで - 多様なユーザー層に届けるAPI提供戦略 / Postman API Night Okinawa 2026 Winter
tasshi
0
170
Patterns of Patterns
denyspoltorak
0
1.3k
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.6k
AgentCoreとHuman in the Loop
har1101
5
200
SourceGeneratorのススメ
htkym
0
160
humanlayerのブログから学ぶ、良いCLAUDE.mdの書き方
tsukamoto1783
0
160
プロダクトオーナーから見たSOC2 _SOC2ゆるミートアップ#2
kekekenta
0
130
[KNOTS 2026登壇資料]AIで拡張‧交差する プロダクト開発のプロセス および携わるメンバーの役割
hisatake
0
180
.NET Conf 2025 の興味のあるセッ ションを復習した / dotnet conf 2025 quick recap for backend engineer
tomohisa
0
120
Featured
See All Featured
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
130
Accessibility Awareness
sabderemane
0
44
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
Balancing Empowerment & Direction
lara
5
860
Skip the Path - Find Your Career Trail
mkilby
0
50
Paper Plane (Part 1)
katiecoart
PRO
0
3.6k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
210
Crafting Experiences
bethany
1
42
Automating Front-end Workflow
addyosmani
1371
200k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
920
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.6k
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