GHC 7.0.x―7.2.1 現在のスレッド実装について
@kazu_yamamoto non-threaded STM では TVar が一つのネイティブスレッド上でしか実行されないことが保障されているので実装上ではロックをかけなくても良い。この実装の違いが1 コアでの性能差になっているみたいです http://j.mp/hGaHme
2011-03-28 18:01:01@kazu_yamamoto このように threaded な RTS と non-threaded な RTS に求められるスペックの違いから、1コア同士の比較なら threaded な実装は non-threaded な実装に比べて遅くなるということです。
2011-03-28 18:06:23@kazu_yamamoto で、この1jコア同士の性能低下が複数コアの場合にも見られるかもしれないから、複数コアで性能をあげたい場合にはちゃんとそれに適した(スケールする)プログラムを書いてね(また性能比較も重要)、と釘を刺しているのが RWH の p.556 の話のはずです。
2011-03-28 18:16:10@kazu_yamamoto MVar でもやはり threaded な RTS ではロックをかけている(厳密にはロックに相当する処理を行っている)のに対し、non-threaded な RTS ではロックをかけないという違いがありました。 http://j.mp/i6PEGr
2011-03-28 19:26:08@kazu_yamamoto はい。atomicModifyIORef では(ソフトウェア的な)ロックではなく、アトミック命令を使って処理の競合を解決しています。 http://j.mp/mPHQOg http://j.mp/nrS6kv http://j.mp/r8C8FF
2011-07-06 21:44:46@kazu_yamamoto .。oO(本当に全くロックをかけていないかどうかは、もうちょっとちゃんと実装を確かめてみる必要がありますが。)
2011-07-06 21:45:44注意: IORef に格納されるのはサンクで、atomicModifyIORef では単純に(格納された値を表現する)サンクを atomic に更新するだけです。サンクによって評価されるべき値がまるごと更新されるわけではありません。
"A monad for deterministic parallelism" [http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/ ] より "the difference is that the update is performed atomically; the contents of the IORef are replaced by a lazy thunk representing the result."
上で紹介した "Scalable I/O Event Handling for GHC" や "Generational garbage collection and floating garbage" [http://blog.johantibell.com/2010/04/generational-garbage-collection-and.html] なども参照のこと。
MVar のロック
@kazu_yamamoto ここで言うロックは、Spinlock + yieldThread(unix では sched_yield)で自作したものですね。 http://j.mp/oc5K5G http://j.mp/pIxSu4 http://j.mp/nfynVm
2011-07-06 21:46:27@kazu_yamamoto futex は思ったほど性能がでないという理由で。現在は直接呼び出してはいません。 http://hackage.haskell.org/trac/ghc/ticket/3553#comment:5
2011-07-06 21:52:45@kazu_yamamoto 1年半前の Linux 事情を反映したものなので、現在はちゃんと性能が出る状況になっているかもしれませんが。c.f. http://www.atmarkit.co.jp/flinux/rensai/watch2009/watch11a.html
2011-07-06 21:53:49@kazu_yamamoto 見た感じ MVar と IORef の実装には mutex (や futex)は使われていないので、RTS で GC やスレッドのスケジューリングなどの処理を行う際に利用される mutex が結果として現れている感じではないでしょうか?
2011-07-06 21:59:26@kazu_yamamoto あるいは、RTS やライブラリで利用するシステムコールの内部で呼ばれる futex が結果として現れている感じかしら。実際に Linux のシステムコールの実装を見てみないことには、確かなことは言えませんが。
2011-07-06 22:02:45@kazu_yamamoto あっ、「直接呼び出していない」と書くよりも「GHCの実装には使ってません」とストレートに書いた方が良かったかもしれませんね。 > futex
2011-07-06 22:17:19@kazu_yamamoto というわけで、前に書いていた 「-threaded RTS の MVar では、コンテキストスイッチが起こる」という直感は正しいですね。yieldThread(sche_yield)を使ってわざとコンテキストスイッチを起こしていると言う形ですが。
2011-07-06 22:09:28STM や TVar のロック
前に話題になっていた GHC の STM の実装を見てました。threaded RTS だと、cas を使って lock を実装 → それを使って STM を実装という感じですね。 http://t.co/2u4V1mwU http://t.co/KEFYBcXe
2011-10-09 19:02:04STM_CG_LOCK はコメントアウトされているため、threaded RTS では STM_FG_LOCKS、threaded でない RTS では STM_UNIPROC の定義が使われるはずです。 http://t.co/nP2YdUCf
2011-10-09 19:02:36どうやら、MVar にしろ [http://t.co/RbydmhOz http://t.co/kTf2Y32C ] 、STM にしろ、GHC の RTS では lock と言っても OS の提供する既成の lock ではなく RTS で自作したものを使っているようです。
2011-10-09 19:04:29GHC 7.2.1現在、OS の提供する lock の使用はScheduler、Taskの生成、削除、GCなどのネイティブスレッドの処理を制御する必要のある部分に限定されている感じですね。 http://t.co/N33SjLDD http://t.co/oPt00WnO
2011-10-09 19:24:21なお、Scheduler、Task の生成、削除、GC などのネイティブスレッドの処理を制御する必要のある部分での、OS の提供する機能を使ったロック(mutex) の実装は以下のような形になっています。 https://github.com/ghc/ghc/blob/ghc-7.2/includes/rts/OSThreads.h https://github.com/ghc/ghc/blob/ghc-7.2/rts/posix/OSThreads.c#L139 https://github.com/ghc/ghc/blob/ghc-7.2/rts/win32/OSThreads.c#L134