並行性と並列性に関する章である「RealWorldHaskell」の本を読んでいます。私の質問は次のとおりです。
Haskellスレッドは実際には1つの「実際の」OSスレッド内の複数の「仮想」スレッドであるため、これは、それらを多数(1000など)作成してもパフォーマンスに大きな影響がないことを意味しますか?つまり、forkIO
を使用してHaskellスレッドを作成することで発生するオーバーヘッドは(ほとんど)無視できると言えますか?可能であれば、太平洋の例を持参してください。
軽量スレッドの概念は、マルチコアアーキテクチャの利点を使用することを妨げませんか?私が理解しているように、2つのHaskellスレッドは、オペレーティングシステムの観点からは実際には単一のスレッドであるため、2つの別々のコアで同時に実行することはできません。または、Haskellランタイムは、複数のCPUを確実に使用できるようにするための巧妙なトリックを実行しますか?
GHCのランタイムは、複数のハードウェアコアに分散される可能性のある、数十億のスパーク、数千の軽量スレッドをサポートする実行環境を提供します。 -threaded
でコンパイルし、+RTS -N4
フラグを使用して、必要なコア数を設定します。
具体的には:
これは、それらを多数(1000など)作成しても、パフォーマンスに大幅な影響がないことを意味しますか?
まあ、 それらの1,000,000を作成する は確かに可能です。 1000はとても安いので、表示されません。 「スレッドリング」などのスレッド作成ベンチマークで、 GHCは非常に優れています であることがわかります。
軽量スレッドの概念は、マルチコアアーキテクチャの利点を使用することを妨げませんか?
どういたしまして。 GHCはマルチコアで実行されています 2004年以降。マルチコアランタイムの現在のステータスは ここで追跡されます。
それはどのようにそれをしますか?このアーキテクチャについて読むのに最適な場所は、論文、 "マルチコアHaskellのランタイムサポート" :です。
GHCランタイムシステムは、物理CPUごとにおよそ1つずつ、少数のオペレーティングシステムスレッドに多重化することにより、数百万の軽量スレッドをサポートします。 .。
Haskellスレッドは、ワーカースレッドと呼ばれる一連のオペレーティングシステムスレッドによって実行されます。物理CPUごとにおよそ1つのワーカースレッドを維持しますが、正確にはどのワーカースレッドが時々変わる可能性があります...
ワーカースレッドは変更される可能性があるため、CPUごとに1つのHaskell実行コンテキスト(HEC)を維持します。 HECは、OSワーカースレッドがHaskellスレッドを実行するために必要なすべてのデータを含むデータ構造です。
作成中のスレッドとその実行場所を監視できます threadscope経由 。ここでは、例えば二分木ベンチマークの実行:
Warp Webサーバーは、これらの軽量スレッドを広範囲に使用して、 非常に優れたパフォーマンス を取得します。他のHaskellWebサーバーも競合他社を煽っていることに注意してください。これは「ワープが良い」というよりも「ハスケルが良い」という意味です。
Haskellは、複数のシステムスレッドに軽量スレッドを分散できるマルチスレッドランタイムを提供します。最大4コアで非常にうまく機能します。それを過ぎて、それらは積極的に取り組んでいますが、いくつかのパフォーマンスの問題があります。
1000個のプロセスを作成するのは比較的軽量です。それをすることについて心配しないでください。パフォーマンスに関しては、ベンチマークする必要があります。
以前に指摘したように、複数のコアは問題なく機能します。異なるOSスレッドでスケジュールすることにより、複数のHaskellスレッドを同時に実行できます。