GHCが各スレッドにスタックを与えるのは私の理解です。なぜこれが必要ですか? GHCはCPSにコンパイルされませんか?スレッドはクロージャーとして簡潔に表現されていませんか?なぜGHCはスレッドごとにスタックを持っていますか?
答えて
あなたの質問にはいくつかの側面があります。
GHCランタイムでの設計決定のキーリファレンスは、''Runtime Support for Multicore Haskell''です。
リコールその
GHCのランタイムシステムは、オペレーティング・システムのスレッドの一握り、各物理CPUについて およそ1にそれらを多重化することにより、軽量スレッド の何百万人をサポートしています。
そして:
各Haskellのスレッドは ヒープに割り当てられているのfi有限サイズのスタック上で実行されます。スレッドの状態は、スタックとともにヒープ割り当てスレッド状態オブジェクト(TSO)に保持されます。 TSOのサイズは、 15ワードにスタックを加えたもので、Haskell スレッドの全体の状態を構成します。 TSOを大きな領域にコピーするとスタックが大きくなり、その後 が再び縮む可能性があります。
GHCはCPSでコンパイルされません。各スレッドは再帰呼び出しを行い、スタックに割り当てる必要があります。スタックをヒープに割り当てられたオブジェクトとして表現することで、より簡単になります。
スレッドは閉鎖以上のものです。
スレッドが実行されると、ヒープとスタックに割り当てが開始されます。したがって、
スレッドのスタック、したがってそのTSOは変更可能です。 スレッドが実行されると、スタックは新しいオブジェクトへのポインタ を累積します。したがって、TSOが古い世代に存在する場合は、記憶された[GCのセット] に追加する必要があります。
スタックが指すガベージコレクションオブジェクトを最適化して、GCがスレッドと同じ物理スレッド上で確実に行われるようにすることができます。ガベージコレクタが実行さらに
、 はTSO及びデータは、それが参照するため 所与のCPU上で実行されたTSOSが同じCPU、 にガベージコレクタによって横切られることが非常に望ましいですそのCPUのローカルの キャッシュに存在する可能性があります。
GHCには、スレッドがスタックとヒープにアクセスできるようにコンパイルする必要があるため、スレッドごとにスタックがあります。各スレッドに独自のスタックを与えることで、スレッドはより効率的に並行して実行できます。スレッドは変更可能なスタックを持っているので、「単なる閉鎖」以上のものです。
"ghcはスレッドをどのように管理していますか?"と答えるのは素晴らしい仕事でしたが、質問は "なぜ?"と尋ねます。私はそれがパフォーマンスと関係があると思っていますが、詳細を教えてください。 –
これは常にパフォーマンスです.GHCの実行モデルは、共有オブジェクトのスレッドによる競合を最小限に抑えようとします(純度を利用するため)。スタックはランタイムによって必要とされるため、スレッドごとのスタックは明白なステップです。 –