ファイバーが複数のプロセッサを利用できないのはなぜですか?


8

ファイバーとスレッドの違いは、ファイバーが協調的にスケジュールされるのに対し、スレッドは先制的にスケジュールされることです。スケジューラのポイントは、CPUを「タイムシェアリング」することによって、それ以外の場合はシリアルプロセッサリソースを並列に動作させる方法のように見えます。ただし、各コアが独自のスレッドを実行しているデュアルコアプロセッサでは、シングルプロセッサが「タイムシェアリング」されていないため、一方のスレッドの実行を一時停止してもう一方のスレッドを続行する必要がないと思います。

それで、スレッドとファイバーの違いがスケジューラーによって中断される方法であり、物理的に別々のコアで実行しているときに中断する必要がない場合、スレッドが可能なときにファイバーが複数のプロセッサーコアを利用できないのなぜですか?

混乱の原因:

..主にウィキペディア

  1. http://en.wikipedia.org/wiki/Fiber_%28computer_science%29

    欠点は、ファイバーがプリエンプティブスレッドを使用せずにマルチプロセッサマシンを利用できないことです。

  2. http://en.wikipedia.org/wiki/Computer_multitasking#Multithreading

    ... [ファイバー]は、複数のプロセッサを搭載したマシンのスレッドの利点の一部またはすべてを失う傾向があります。

回答:


9

質問で指摘したように、主な違いは、スケジューラーがスレッドをプリエンプトするかどうかです。プログラマーがデータ構造の共有や「スレッド」間の同期について考える方法は、プリエンプティブシステムと協調システムでは大きく異なります。

協調システム(多くの名前で呼ばれる、協調マルチタスク非プリエンプティブマルチタスクユーザーレベルスレッドグリーンスレッド、およびファイバーは現在5つの一般的なものです)では、プログラマーはコードがアトミックに実行される限り、アトミックに実行されることが保証されますシステムコールやを呼び出しませんyield()。これにより、複数のファイバー間で共有されるデータ構造の処理が特に簡単になります。クリティカルセクションの一部としてシステムコールを実行する必要がない限り、クリティカルセクションにマークを付ける必要はありません(たとえば、ミューテックスlockunlock呼び出しで)。したがって、次のようなコードで:

x = x + y
y = 2 * x

プログラマーは、他のファイバーがxy変数を同時に処理することを心配する必要はありません。 xそしてy他のすべての繊維の観点からアトミック一緒に更新されます。同様に、すべてのファイバーは、ツリーのようないくつかのより複雑な構造を共有することができ、コールtree.insert(key, value)は、ミューテックスやクリティカルセクションによって保護される必要はありません。

対照的に、プリエンプティブマルチスレッドシステムでは、真の並列/マルチコアスレッドの場合と同様に、明示的なクリティカルセクションがない限り、スレッド間で命令を可能な限りインターリーブできます。割り込みとプリエンプションは、任意の2つの命令の間になる可能性があります。上記の例では:

 thread 0                thread 1
                         < thread 1 could read or modify x or y at this point
 read x
                         < thread 1 could read or modify x or y at this point
 read y
                         < thread 1 could read or modify x or y at this point
 add x and y
                         < thread 1 could read or modify x or y at this point
 write the result back into x
                         < thread 1 could read or modify x or y at this point
 read x
                         < thread 1 could read or modify x or y at this point
 multiply by 2
                         < thread 1 could read or modify x or y at this point
 write the result back into y
                         < thread 1 could read or modify x or y at this point

したがって、プリエンプティブシステムまたは真に並列なスレッドを備えたシステムで正しく機能するためにはlock、最初のミューテックスunlockと最後のミューテックスのような何らかの同期ですべてのクリティカルセクションを囲む必要があります。

したがって、ファイバーは、プリエンプティブスレッドや真に並列なスレッドよりも、非同期I / Oライブラリに似ています。ファイバースケジューラが呼び出され、長い待機時間のI / O操作中にファイバーを切り替えることができます。これにより、クリティカルセクションの周りの同期操作を必要とせずに、複数の同時I / O操作の利点を得ることができます。したがって、ファイバーを使用すると、プリエンプティブスレッドまたは真に並列なスレッドよりもプログラミングの複雑さが少なくなる可能性がありますが、ファイバーを本当に同時にまたはプリエンプティブに実行しようとすると、クリティカルセクションの周りの同期の欠如は悲惨な結果につながります。


1つは、ユーザーレベルのスレッドシステムが(ほとんどの)CPUコア全体に(多くの)ユーザーレベルのスレッドを分散するハイブリッドシステムです。2。「ベアメタル」でプログラミングする場合の事実、プリエンプションなしでマルチプロセッシングを取得することが可能です。
dfeuer 2015年

1
@dfeuer私は、マルチプロセッシングを利用するために考えられるすべての異なる方法を求めているとは思いません。私が読んだときの質問は、「ファイバー(非プリエンプティブタスクとも呼ばれます)がプリエンプティブスレッドのように扱われないのはなぜですか?」です。実際の並列処理を想定している場合は、正しく同期する必要があるため、「ファイバー」がなくなります。
Wandering Logic

1
美しい答え。プログラムは割り込みポイントを指定するまではプログラムが共有リソースへの排他的アクセスを持っていると想定するため、ファイバーは安全性を保証できません。明らかに、複数の真に並列なノードが同じデータと相互作用している場合のより安全な仮定。
James M. Lay

6

答えは実際には可能であるということですが、それを望まないのです。

ファイバーは、スケジューリングの方法を制御できるため使用されます。したがって、プログラマーはいつどのファイバーを実行するかを言っているので、ファイバーを使用していくつかのアルゴリズムを設計する方がはるかに簡単です。ただし、2つのファイバーを2つの異なるコアで同時に実行する場合は、手動でスケジュールして、実行する必要があります。

スレッドは、OSに対して実行されているコードを制御します。その代わりに、OSが多くの醜いタスクを処理します。一部のアルゴリズムは、プログラマーが特定の時間にどのコードを実行するかについてあまり知らないため、より困難になります。そのため、予期しないケースがより多く現れる可能性があります。ミューテックスやセマフォなどのツールがOSに追加され、プログラマーを困らせることなく、スレッドを有用なものにして、不確実性のいくつかを打ち消すだけの十分な制御をプログラマーに与えます。

これは、協調的またはプリエンプティブよりもさらに重要なものにつながります。スレッドはOSによって制御される一方で、ファイバーはプログラマーによって制御されます。

別のプロセッサでファイバーを生成する必要はありません。これを行うためのアセンブリレベルのコマンドは非常に複雑で、多くの場合、プロセッサ固有のものです。これらのプロセッサを処理するためにコードの15の異なるバージョンを作成する必要はないので、OSを使用します。OSの仕事は、これらの違いを取り除くことです。結果は「スレッド」です。

繊維は糸の上を走ります。彼らは自分で実行されません。したがって、2つのファイバーを異なるコアで実行したい場合は、2つのスレッドをスポーンして、それぞれにファイバーを実行できます。ファイバーの多くの実装では、これを簡単に行うことができます。マルチコアのサポートはファイバーではなく、スレッドからのものです。

独自のプロセッサ固有のコードを記述しない限り、スレッドを作成してそれぞれにファイバーを割り当てることではできなかった、複数のコアにファイバーを割り当てることでできることは何もないことを示すのは簡単になります。API設計の私のお気に入りのルールの1つは、「APIへのすべての追加が完了したときではなく、取り出すものが他に見つからなくなったときにAPIが完了する」です。 マルチコアはスレッド上でファイバーをホストすることで完全に処理されるので、そのレベルでマルチコアを追加してファイバーAPIを複雑にする理由はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.