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
570
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
750
Other Decks in Programming
See All in Programming
Why Jakarta EE Matters to Spring - and Vice Versa
ivargrimstad
0
1.1k
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
910
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
190
Jakarta Concurrencyによる並行処理プログラミングの始め方 (JJUG CCC 2024 Fall)
tnagao7
1
290
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
110
Realtime API 入門
riofujimon
0
150
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
タクシーアプリ『GO』のリアルタイムデータ分析基盤における機械学習サービスの活用
mot_techtalk
4
1.4k
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
860
みんなでプロポーザルを書いてみた
yuriko1211
0
260
Featured
See All Featured
How GitHub (no longer) Works
holman
310
140k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
Building Your Own Lightsaber
phodgson
103
6.1k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Documentation Writing (for coders)
carmenintech
65
4.4k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
The World Runs on Bad Software
bkeepers
PRO
65
11k
Side Projects
sachag
452
42k
Done Done
chrislema
181
16k
Happy Clients
brianwarren
98
6.7k
For a Future-Friendly Web
brad_frost
175
9.4k
It's Worth the Effort
3n
183
27k
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