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
Ruby の FiberScheduler を布教したい
Search
Daiki Kudo
May 13, 2022
Programming
0
380
Ruby の FiberScheduler を布教したい
Daiki Kudo
May 13, 2022
Tweet
Share
Other Decks in Programming
See All in Programming
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
700
MCPサーバー「モディフィウス」で変更容易性の向上をスケールする / modifius
minodriven
4
610
Blazing Fast UI Development with Compose Hot Reload (droidcon London 2025)
zsmb
0
450
Module Proxyのマニアックな話 / Niche Topics in Module Proxy
kuro_kurorrr
0
1.3k
Towards Transactional Buffering of CDC Events @ Flink Forward 2025 Barcelona Spain
hpgrahsl
0
120
CSC509 Lecture 11
javiergs
PRO
0
280
AI駆動開発カンファレンスAutumn2025 _AI駆動開発にはAI駆動品質保証
autifyhq
0
120
CSC305 Lecture 12
javiergs
PRO
0
250
One Enishi After Another
snoozer05
PRO
0
180
CSC305 Lecture 10
javiergs
PRO
0
330
CSC509 Lecture 08
javiergs
PRO
0
280
ボトムアップの生成AI活用を推進する社内AIエージェント開発
aku11i
0
1.4k
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
54
7.9k
Six Lessons from altMBA
skipperchong
29
4k
Designing Experiences People Love
moore
142
24k
KATA
mclloyd
PRO
32
15k
Gamification - CAS2011
davidbonilla
81
5.5k
The Invisible Side of Design
smashingmag
302
51k
Navigating Team Friction
lara
190
15k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Documentation Writing (for coders)
carmenintech
76
5.1k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.7k
Automating Front-end Workflow
addyosmani
1371
200k
How STYLIGHT went responsive
nonsquared
100
5.9k
Transcript
Ruby の FiberScheduler を布教したい 工藤大暉 @kudojp
そもそも、FiberSchedulerって何...? • Rubyでシングルスレッドで並行処理を行うために使われる概念 • Ruby3.0 で導入されました
アジェンダ 1. Rubyにおける並行処理 2. FiberSchedulerによる並行処理の書き方 3. FiberSchedulerによる並行処理の仕組み 4. FiberSchedulerを自作した話
アジェンダ 1. Rubyにおける並行処理 2. FiberSchedulerによる並行処理の書き方 3. FiberSchedulerによる並行処理の仕組み 4. FiberSchedulerを自作した話
待ち時間に別の処理を行う = 並行処理 プログラムを早くする方法は他にもある • CPU高速化 • CPUの実行コア数を増やす (並列処理) でも今回注目するのは並行処理。
並行処理とは? • 実行したい処理を「タスク」に切り分ける • 複数のタスクを切り替えながら実行する 📝 切り替えのタイミングは「実行中のタスクが待ち状態になった時」
並行処理の実現方法を2種類紹介します ①タスクごとにスレッドを切って実行 ②シングルスレッド内でタスクを切り替えながら実行
①タスクごとにスレッドを切って実行 メリット • OSの機能にただ乗りでき、複雑な実装が不要 デメリット • 作成したスレッドがメモリを多く消費する (1MBオーダー) • 処理によっては、レースコンディションが発生する
👉 (実装を頑張れるなら)シングルスレッド内でタスク切り替えをしたい
②シングルスレッド内でタスクを切り替えながら実行 Ruby の場合、 Fiber インスタンスを用いてタスクを表す。 実行する Fiber を切り替えながら処理を進める Fiber インスタンス
「待ち」が発生したタイミングで 切り替える Fiber インスタンス Fiber インスタンス
「待ち」が発生したタイミングでFiberを切り替える そもそも • 「Fiber」とは? • 「待ち」 とは?
Fiberとは何か?
Fiberとは • 処理を内包できます • 処理の中に実行を中断する箇所が設定できる • 前回中断した箇所から処理を再開できる Ruby言語の中にFiberクラスが定義されています
None
「待ち状態」とは何か?
待ち状態 = システムコールの応答待ち 例えばRubyプログラムがファイルのデータを読み取りたい時、 1. OSにシステムコール(open)を投げる 2. OSにシステムコール(read)を投げる OSはreadを受け取ったら、ディスク上のファイルのデータを取得し、それをメモ リ上に乗っけて、Rubyプログラムと共有する
この応答を待っている時間が、「待ち」時間。
「待ち」発生のタイミングでFiberを切り替えるために システムコールの応答を長々と待つのをやめたい
「OSよ。準備できた分だけでいいから瞬時に返して」 readシステムコールの応答に時間がかかるなら、 OS「これだけしか準備できてないです。あとでもう一回コールしてください🤙 」 と答えてほしい。 👉 「non blocking モード」で readシステムコールをしたらこの挙動になる
ノンブロッキングReadとFiberの切り替え (パターン1) Rubyプログラム「OSさん、ファイルA をReadしたいです」 OS「現在用意できてるデータは全くありません」 👉 Rubyプログラムは 現在のFiberを中断し、別のFiberを再開する
ノンブロッキングReadとFiberの切り替え (パターン2) Rubyプログラム「OSさん、ファイルA をReadしたいです」 OS「全部じゃないけど、用意できてる分だけ返します」 👉 RubyプログラムはこのFiberの実行を継続する(= もう一度readコールを行う)
ノンブロッキングReadとFiberの切り替え (パターン3) Rubyプログラム「OSさん、ファイルA をReadしたいです」 OS「もう全部返し終わってます。これ以上ありません」 👉 RubyプログラムはこのFiberの実行を継続する
ノンブロッキングReadを使えば 「待ち発生のタイミングでFiberを切り替える」ことが可能 ✅
Rubyでは、バージョン3.0 以降 Fiberを利用した非同期処理を言語レベルでサポートしている。
アジェンダ 1. Rubyにおける並行処理 2. FiberSchedulerによる並行処理の書き方 3. FiberSchedulerによる並行処理の仕組み 4. FiberSchedulerを自作した話
「FiberSchedulerの並行処理の書き方」 ① ① FiberSchedulerを初期化し、現在のThreadに登録 ② Fiber.scheduleを実行する。 並行に実行したい処理をブロック引数で渡す ② ②
①メインの処理 ②Fiber1がブロックするまで ③Fiber2がブロックするまで ④メインの処理 ⑤イベントループ - Fiber1のブロック以降 - Fiber2のブロック以降 ①
② ④ ③ ⑤ ⑤ Fiber1 Fiber2 処理の実行順序
アジェンダ 1. Rubyにおける並行処理 2. FiberSchedulerによる並行処理の書き方 3. FiberSchedulerによる並行処理の仕組み 4. FiberSchedulerを自作した話
FiberScheduler は Rubyランタイムの相棒 Rubyランタイムは、FiberSchedulerを駆使して、並行処理を実現しています。
FiberSchedulerの特性を4つ説明します
①1スレッドに1つ、FiberSchedulerインスタンスが登録されます
Fiber.schedule 実行時、そのブロック引数を内包するFiberが初期化されます。 そのスレッドに登録されているFiberSchedulerインスタンスがこれを保持します。 ②FiberSchedulerインスタンスは、Fiberタスクの集合を保持します
③FiberScheduler#closeメソッドが実装されています FiberScheduler#close • FiberSchdulerが保持している未完了のFiberタスクを全て実行し 終える そのスレッドのメインの処理が終了した後に実行される。
④「待ち状態が発生したら現在のタスクを中断する」ロジックを持っています ファイル読み込みの例で説明します。 理想 File.read("text1.txt") を実行した際、待ち状態になったら現在のFiberを中断する🟥 現実 Ruby標準の File.read の実装には 🟥
のロジックは入っていない 💡 Rubyランタイムは、FiberScheduler#io_readを利用してこれを可能にします。
FiberScheduler#io_read IO.readの 並行実行のために使われるバージョン • ノンブロッキング readを行う • 待ち状態になったら現在のFiberを中断する • 中断したFiberをFiberSchedulerのインスタンス変数として保持する
🌟Fiber.scheduleの ブロック内の場合 システムコールを 含むC実装 IO.read FiberScheduler#io_read File.read
以下のメソッドも同じ仕組みです ブロッキングするメソッドは、FiberSchedulerに代替メソッドを持つ • IO#write → FiberScheduler#io_write • Kernel#sleep → FiberScheduler#kernel_sleep
• Timeout#timeout → FiberScheduler#timeout_after
以上、FiberSchedulerの特性4つでした ①1スレッドに1つ、FiberSchedulerインスタンスが登録されます ② FiberSchedulerインスタンスは、Fiberタスクの集合を保持します ③ FiberScheduler#close メソッドが実装されています ④「待ち状態が発生したら現在のタスクを中断する」ロジックを持っています 【朗報】FiberSchedulerさん、超有能だったwww
「FiberSchedulerを使ってRubyで並行処理をかいていこー💪」 完
待って!以下を思い出してください FiberSchedulerのgemを外部からインポートしてます
FiberSchedulerの実装はRubyに含まれていない Ruby3.2現在、含まれていません。 ただし、インターフェイスは規定されています。 👉 このインターフェイスを満たすスケジューラーを各自実装して使用する
色んなFiberScheduler が gemとしてリリースされている これらを使用する。あるいは、、、
FiberSchedulerを自作する!
アジェンダ 1. Rubyにおける並行処理 2. FiberSchedulerによる並行処理の書き方 3. FiberSchedulerによる並行処理の仕組み 4. FiberSchedulerを自作した話
FiberSchedulerを自作するメリット • 楽しい ◦ 性能をあげるためにアルゴリズムを考える必要がある ◦ 低レイヤーを掘って調査する必要がある • OSS開発者への道が開ける ◦
Ruby3.0で導入されたばかりなので、開発が活発。 ◦ 実装中に得られたアイデアをRuby言語に取り入れられるかもしれない❗️ 👉 自作してます
ここから自分語りタイムです
こんな感じで進めてます • 2022年の元日に作り始めた • 2週間に1メソッドくらいのスピードで書いてる • 詰まった時には ◦ オープンソースのFiberSchedulerの実装を参考にする ◦
Rustで非同期スケジューラを実装したパイセンの @k-nasa に話を聞く
こんなところが大変です • 並行処理のテストを書くのに慣れていない • デバッグのやり方が手探り • Fiberの扱いが難しい • 発生するエラーの考慮漏れが発生しそう
実装完成したらgemとしてリリース予定です (名前募集中)
完