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
Kotlinで実装するCPU/GPU 「協調的」パフォーマンス管理
Search
matuyuhi
November 01, 2025
Programming
0
80
Kotlinで実装するCPU/GPU 「協調的」パフォーマンス管理
2025/11/01 kotlin fest 2025の資料です
https://2025.kotlinfest.dev/timetable/1719033600_b/
matuyuhi
November 01, 2025
Tweet
Share
Other Decks in Programming
See All in Programming
Devoxx BE - Local Development in the AI Era
kdubois
0
150
CSC305 Lecture 10
javiergs
PRO
0
310
When Dependencies Fail: Building Antifragile Applications in a Fragile World
selcukusta
0
110
Blazing Fast UI Development with Compose Hot Reload (Bangladesh KUG, October 2025)
zsmb
2
400
O Que É e Como Funciona o PHP-FPM?
marcelgsantos
0
220
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
580
外接に惑わされない自システムの処理時間SLIをOpenTelemetryで実現した話
kotaro7750
0
110
スマホから Youtube Shortsを見られないようにする
lemolatoon
27
34k
NixOS + Kubernetesで構築する自宅サーバーのすべて
ichi_h3
0
1.3k
社会人になっても趣味開発を続けたい! / traPavilion
mazrean
1
110
Software Architecture
hschwentner
6
2.4k
釣り地図SNSにおける有料機能の実装
nokonoko1203
0
200
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
The Language of Interfaces
destraynor
162
25k
Into the Great Unknown - MozCon
thekraken
40
2.1k
Raft: Consensus for Rubyists
vanstee
140
7.2k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
Become a Pro
speakerdeck
PRO
29
5.6k
Making Projects Easy
brettharned
120
6.4k
Done Done
chrislema
185
16k
Typedesign – Prime Four
hannesfritz
42
2.8k
Transcript
Kotlinで実装するCPU/GPU 「協調的」パフォーマンス管理 Kotlin Fest 2025 yuhi yamane / @matuyuhi
目的 ADPFの“難しさ”を Kotlinの型とFlowで“できない設計”に置き換える ADPF = Android Dynamic Performance Framework
• 型で契約を保証するDSLの作り方 • callbackFlow背圧の3パターン(状態/トレンド/高頻度) • JNIは檻の中(最小権限+安全な解放) ゴール
1.Android 15で進化したADPFによるCPU/GPU協調制御の概要 2.ADPF利用の壁 C/C++ APIとJNIの課題 3.FlowとDSLでネイティブAPIを抽象化で誤用不能の型を作る 4.コールバックの注意点や制御戦略 アジェンダ
なぜ? • 長時間負荷→サーマル・スロットリング→FPS/応答低下 • 回避は無理、協調で“落ち幅”を制御 • アプリ → ADPF →OSにヒントを出せる時代
OS OS (DVFS/scheduling) App (目標ms/実測ms) ADPF(Android Dynamic Performance Framework)とは •
ゲーム等の高負荷アプリが熱暴走せず安定動作するよう性能と熱を動的制御 • Android 15から作業時間を報告し、 OSが両者の周波数を同時に調整し最適化 • 従来のOS任せのDVFSに対し、ADPFはアプリから追加情報を渡し最適化を支援 https://developer.android.com/games/optimize/adpf https://source.android.com/docs/core/power/performance
ADPF利用の課題
ADPF利用の課題 • JNIの壁 ADPFの強力なAPIはC/C++実装で、Kotlin/Javaから直接扱えない • JNI呼び出しの煩雑さ ネイティブコード記述&JNIブリッジが必要 • 型安全性の欠如 JNI経由ではコンパイル時チェックが弱く、誤った引数やリソース管理漏れのリスク
Flow+DSLでクリーンに抽象化
• ADPFの契約 時間計測を統一(SystemClock.uptimeNanos)し、1サイクル1回の報告を厳守など • Flow活用 callbackFlowでネイティブイベントをReactiveにラップ • DSL活用 型安全ビルダーDSLでネイティブAPI操作を宣言的に記述(JNI詳細を意識せず使える) Flow+DSLでクリーンに抽象化
煩雑なJNI処理を意識せず、Kotlinらしい可読性と安全性でコードを記述
イベント種別ごとの戦略 • 状態 最新だけ必要? → conflate() 常に最新1件のみ保持 • トレンド ざっくり傾向?
→ sample(推奨間隔) 定期サンプリング • 高頻度 量が多い? → buffer(..., DROP_OLDEST) 古いデータを破棄し遅延防止
• 登録/解除は厳密に:awaitClose { removeListener() } • コールバック実行スレッド(MainExecutor) → 処理はで別スレッドへ •
必要に応じて buffer / conflate / sample / mapLatest を適用 • 演算子は意味で選ぶ ⚬ 最新のみ?間引き? 最新優先? • → Kotlin側で collect { … } するだけでデバイス状態をリアクティブに監視可能に Flow化の設計 (callbackFlow活用パターン)
thermalStatusFlow の実装 状態は最新だけで十分 → .distinctUntilChanged().conflate() で連続重複や古い値を除去 リーク対策: awaitClose { remove…
} でリスナー登録を確実に解除 ↓ 温度が警告レベル以上になったら setPreferPowerEfficiency(true) で 省電力モードに切替えなど
温度に応じてFPSレンジを落として発熱を抑制 thermalStatusFlowの利用
ExoPlayer:温度でSD上限にトラック選択 thermalStatusFlowの利用
DSL設計 API android.os.PerformanceHintManager アプリ⇄OSのヒント用チャネル ADPFの管理API • Session(作る→使う→閉じる) ⚬ 対象スレッド(TID)と目標時間(target)を束ねたハンドル ⚬
WorkDurationで測定結果を送信 • 主な操作 ⚬ updateTargetWorkDuration(...) / setPreferPowerEfficiency(...) ⚬ reportActualWorkDuration(WorkDuration)(1サイクル1回) ⚬ preferredUpdateRateNanos()(送信の上限目安)
基本の書き方
• 時刻の混入:SystemClock.elapsedRealtimeNanos() vs System.nanoTime() • 必須の踏み忘れ:WorkDuration( )〜 の設定漏れがコンパイルで見えない • フェーズ混在:測定記述の中から目標時間(target)更新を呼べてしまう
• TID誤り:Thread.currentThread( ).id を渡すなど、Linux TID 以外を指定しがち • 過剰送信:preferredUpdateRateNanos を無視して連打(意味がない/無駄に電力) • ライフサイクル:close( ) 漏れ/複数スレッドからの呼び出しで非スレッドセーフ 現状の問題点
専用の型 • 時刻 • TID 専用型で混入をコンパイルで拒否し、誤指定を防ぐ
type-stateでコンパイル時に強制 TS: ThreadsMissing TT: TargetMissing threads(Tid) TS: ThreadsSet TT: TargetMissing
TS: ThreadsSet TT: TargetSet target(N) build() SessionBuilder
エラー 実行可
android.os.PerformanceHintManager.Session へブリッジ
None
ネストしたレシーバの外側(control)と内側(report)の両方を同時に可視 • 意味の異なる操作が同一スコープで可視 • 時間軸の破壊(1サイクル=1報告の仮定が崩壊) • 型が守ってくれない このまま利用した場合
report { ... } の中は測定結果だけ、updateTarget(...) はサイクルの外で行う ──フェーズを分けるべき @HintDsl で内から外は不可視に コンパイルエラーに
イベント種別ごとの戦略
イベント種別ごとの戦略 • sample()で可読な頻度に • 連続的に変化する値の傾向を見る • データ量を間引く トレンド 連続的に変化する値
• buffer()で容量を決めて古いものから捨てる • 遅延で制御信号が古くなるのを防ぐ イベント種別ごとの戦略 高頻度 毎フレームのイベントなど
• conflate()で最新だけ通す • 現在の状態だけ分かれば十分な情報 イベント種別ごとの戦略 状態の取り扱い 現在の最新状態だけ • bufferのショートカット [Flow.conflate()
== Flow.buffer(.... DROP_OLDEST)] https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/conflate.html
ADPFの限界と対処法 • 効きにくいケース I/Oボトルネックや瞬間的ジョブでは効果が薄い • Headroomの不安定 端末差やNaN値あり → 長い間隔でサンプル、無効ならThermalStatusのみで対処 •
ヒント送信頻度 フレーム単位が実質上限(それ以上細かく送っても無意味)
JNI連携における安全策 • RAII(use{}でclose漏れゼロ) • callbackFlow の解除一点化(awaitClose{ unregister(...) }) • 失敗の三態化(例外を“沈めない”で型に出す)
JNI連携における安全策 • RAII(use{}でclose漏れゼロ) • Session側をCloseable/AutoCloseable • use{}の外でSessionを持ち回らない。 RAII = Resource
Acquisition Is Initialization
JNI連携における安全策 • 失敗の三態化(例外を沈めないで型に出す) • 返り値を3種に • Success: 想定した挙動 • Limited:
OSの制限ありの非エラー • Failed: 復帰不可能、要調査
まとめ Flowで運び、DSLで守り、JNIの複雑さは内側に封じる 型で表現した契約により、安全なネイティブ活用が可能になる • Flowでデータを輸送 イベントの種類に応じた背圧で無駄なくOSへヒントを届ける • DSLで契約を保証 型システムで単位や手順の誤りを事前に排除し、意味をコードに反映 •
JNIの詳細は封じ込め 危険な処理は内側に隠蔽し、高度な制御をKotlinからシンプルに扱う
参考 • Performance Hint API https://developer.android.com/games/optimize/adpf/performance-hint-api • PerformanceHintManager.Session https://developer.android.com/reference/android/os/PerformanceHintManager.Session •
WorkDuration https://developer.android.com/reference/android/os/WorkDuration • Thermal API https://developer.android.com/games/optimize/adpf/thermal • Kotlin Flow https://developer.android.com/kotlin/flow • Type-Safe Builders https://kotlinlang.org/docs/type-safe-builders.html Thanks!