Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

GoLab2025 Recap

Avatar for kuro kuro
December 07, 2025

GoLab2025 Recap

GoLab2025 Recapの発表スライドです。
https://gocon.connpass.com/event/374056/

Avatar for kuro

kuro

December 07, 2025
Tweet

More Decks by kuro

Other Decks in Programming

Transcript

  1. 今回の発表の構成 1. Raiza Claudinoさんの「Smarter Locks: Diving into Go 1.24’s Mutex

    Spin Optimisation (https://golab.io/talks/smarter-locks-diving-into-go-1-24-s-mute x-spin-optimisation)」というトークのrecap 2. 海外登壇のススメ 3. おまけ
  2. Issue #68578 • 2024年7月に作成されたissue。 • 1つのmutexに負荷が集中すると、プログラム全体が遅くなる。 • しかも一度遅くなると回復しにくい。 Part of

    my experience with runtime.mutex values is that process-wide demand for a single mutex can slow the program to a crawl. 引用: https://github.com/golang/go/issues/68578
  3. ベンチマークの結果 Intel i7-13700H (linux/amd64), Go 1.23rc2 での計測結果: • バッファ付きチャネルでsend/receiveを200回繰り返すベンチマーク •

    チャネル操作の内部でruntime.mutexのlock/unlockが呼ばれる ⇨スレッド数を増やすたびにスループットが半減していく。並行度を増したのに遅くなる。 引用:https://github.com/golang/go/issues/68578 GOMAXPROCS 実行時間 ベースラインとの比較 1 3.167µs - 4 6.527µs 約2倍遅い 8 13.96µs 約4倍遅い 12 29.16µs 約9倍遅い 20 44.36µs 約14倍遅い
  4. CPUプロファイルを見てみる • 対象となる時間の合計31.32秒(20スレッドの合計)のうち • 27.74秒(88%)がlock2の中 • さらにその70%がprocyield(スピン待ち) Duration: 1.78s, Total

    samples = 31.32s (1759.32%) runtime.lock2 27.74s 88.57% ├─ runtime.procyield 19.50s 70.30% ← スピン待ち ├─ runtime.futexsleep 2.74s 9.88% ← OSでのスリープ └─ runtime.osyield 0.84s 3.03% 引用: https://github.com/golang/go/issues/68578
  5. ロックを待つ 2つの方法 Spinning(スピン) • 「ロック空いた?まだ?空いた?まだ?」を繰り返す⇨ロックが空いたらすぐ に取れる • 待っている間もCPUを消費 Sleeping(スリープ) •

    OSに「起こしてくれるまで寝る」と伝えて待つ⇨起きるのに時間がかかる • CPUは他のスレッドに譲る(寝ている間はCPUは消費しない) The Go gopher was designed by Renée French.
  6. 時間の違い It looks like the time a thread in lock2

    takes to go to sleep is over 100 times longer than the runtime's fastest critical sections. 引用: https://github.com/golang/go/issues/68578 • lock2で、スリープするまでのスピン時間 > クリティカルセクション (ロックを取ってからアンロックするまでの時間)×100〜となっている。 • この差が問題を引き起こす。
  7. キャッシュ競合が mutexを遅くする • 読むだけならキャッシュを共有できる。 • でも書き込むと、他のCPUキャッシュを全部無効化する必要がある。 • スピンしてるスレッドが多いほど、キャッシュを持つCPUコアが増える。 ⇨無効化のコストが高くなる ⇨書き込み(lock/unlock)が遅くなる。

    Having the state word in cache for read access requires it not be writeable by any other processors. Writing to that memory location requires the hardware to invalidate all cached copies of that memory, one in each processor that had loaded it for reading. 引用: https://go.googlesource.com/proposal/+/master/design/68578-mutex-spinbit.md
  8. 従来の問題のまとめ 1. クリティカルセクションが短い。 2. unlockが頻繁に呼ばれる。 3. unlockのたびに「寝てる人いる?起こそう」とやる。 4. でもスリープするまでの時間がクリティカルセクションよりも100倍以 上長い。

    5. 起こすペースが、スリープするペースを上回る。 6. みんな起きてスピンしてる状態になる。 ⇨ GOMAXPROCSが多いほど顕著 7. キャッシュラインの競合が激化する。 8. lock/unlockがさらに遅くなる。
  9. 従来の設計 : Tristate mutex.keyの状態は3つ。 0 : unlockedで、誰もロックを持ってない状態。 1 : lockedで、誰かがロックを持っていて、待ってるOSスレッド(M)はいない状

    態。 2 : locked+sleepersで、誰かがロックを持っていて、寝て待ってるOSスレッド (M)もいる状態。 • 0と1の間でlock/unlockが行われる(競合なしの場合) • 競合が発生すると2になり、sleepersがいることを示す
  10. 新設計: Spinning bit • 「今スピンしてるスレッドがいるか」を記録するビットを追加。 • spinning bit = 「今誰かがスピン中か」を示すフラグ

    • このビットが立っていれば、unlockで追加のスレッドを起こさない Expand the mutex state word to include a new flag, "spinning". Use the "spinning" bit to communicate whether one of the waiting threads is awake and looping while trying to acquire the lock. 引用: https://go.googlesource.com/proposal/+/master/design/68578-mutex-spinbit.md
  11. Spinning bitのlock2の流れ 1. mutex.keyを1に変えようとしてロックを試みる 2. 失敗したら、spinning bitを取りに行く - 取れた→ スピンする権利がある

    → スピン開始 - 取れなかった → 既に誰かがスピン中 → 即スリープ 3. スピンしてロックが取れたら、spinning bitをクリア
  12. 参考 • runtime: improve scaling of lock2 · Issue #68578

    · golang/go • Proposal: Improve scalability of runtime.lock2 • CL 601597(futex版) https://go.dev/cl/601597 • CL 620435(cross-OS版) https://go.dev/cl/620435 • Go 1.24 Release Notes - The Go Programming Language
  13. 1.カンファレンスを探す • 基本的には Go Wiki: Go Conferences and Major Events(https://go.dev/wiki/Conferences)から探 す。

    • また、Golang Events - Conferences & Meetups (https://www.golangjobs.tech/events)も良さそう。 • 注意としては、更新が気まぐれなので、過去のものを見 て、そのカンファレンスが今年(or来年)開催されるかどう かこまめにチェックする。(毎年開催されるわけではない)
  14. 1.カンファレンスを探す • GopherCon,GopherCon UK,GoWest等は航空券代、ホテル 代、参加費がカバーされる。 • GoLabはホテル代、参加費のみカバーされる。 • それ以外は参加費のみのカバーの場合が多い。 ⇨

    その場合に、「Gophers Japan 海外カンファレンススカラー シップ」のおかげでハードルがかなり下がります🙇 https://x.com/gophers_jp/status/193 7525520155234567?s=20
  15. 3.発表の準備をする • 内容はプロポーザルに沿ってひたすら考える。 • 「内容」も大事だが、初挑戦なので、「英語っぽく話す」こと を意識した。(そもそも伝わらないと意味がないので) • COEFL Go-JP #3

    ~海外登壇直前練習スペシャル〜 (https://gophers-ex.connpass.com/event/3649 24/)で一度人前で話すことを練習できたのがとても良かっ た。 • YouTubeで海外カンファレンスの発表を見たり、 NaturalReader(https://www.naturalreaders.com /online/) っていうアプリに課金して読み上げてもらった のを聴いたりしていた。