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
370
Ruby の FiberScheduler を布教したい
Daiki Kudo
May 13, 2022
Tweet
Share
Other Decks in Programming
See All in Programming
そのAPI、誰のため? Androidライブラリ設計における利用者目線の実践テクニック
mkeeda
2
260
2025 年のコーディングエージェントの現在地とエンジニアの仕事の変化について
azukiazusa1
22
11k
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
270
ぬるぬる動かせ! Riveでアニメーション実装🐾
kno3a87
1
210
RDoc meets YARD
okuramasafumi
4
170
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
0
400
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
120
testingを眺める
matumoto
1
140
Introducing ReActionView: A new ActionView-compatible ERB Engine @ Rails World 2025, Amsterdam
marcoroth
0
630
1から理解するWeb Push
dora1998
7
1.8k
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
220
「手軽で便利」に潜む罠。 Popover API を WCAG 2.2の視点で安全に使うには
taitotnk
0
830
Featured
See All Featured
Thoughts on Productivity
jonyablonski
70
4.8k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Designing Experiences People Love
moore
142
24k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
A better future with KSS
kneath
239
17k
Music & Morning Musume
bryan
46
6.8k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.5k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
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としてリリース予定です (名前募集中)
完