20

最近GrandCentralDispatchを学んだので、マルチスレッドコードが(GCDを使用して)非常に直感的であることがわかりました。ロックが不要であるという事実(および内部でロックレスデータ構造を使用するという事実)、およびAPIが非常に単純であるという事実が気に入っています。

今、私はpthreadを学び始めており、その複雑さに少し圧倒されざるを得ません。スレッド結合、ミューテックス、条件変数-これらすべてはGCDでは必要ありませんが、pthreadでは多くのAPI呼び出しがあります。

pthreadはGCDに勝る利点を提供しますか?それはより効率的ですか?pthreadがGCDでは実行できないこと(カーネルレベルのソフトウェアを除く)を実行できる通常のユースケースはありますか?

クロスプラットフォームの互換性に関しては、私はあまり心配していません。結局のところ、libdispatchはオープンソースであり、Appleはクロージャの変更をGCCへのパッチとして置き換え、clangはクロージャをサポートしており、すでに(FreeBSDを除く)、Apple以外のGCDの実装がいくつか見られ始めています。私は主にAPIの使用に興味があります(特定の例は素晴らしいでしょう!)。

4

6 に答える 6

16

私は別の方向から来ています:pthreads私のアプリケーションで使い始めましたが、最近C++11に置き換えましたstd::thread。現在、私は疑似ブーストスレッドプールのような高レベルの構造、さらに抽象的なIntelのスレッディングビルディングブロックで遊んでいます。GCDはTBB以上であると思います。

いくつかのコメント:

  • imho、pthreadはGCDよりも複雑ではありません。基本的なコアでは、pthreadに含まれるコマンドは実際にはごくわずかです(ほんの一握り:OPに記載されているコマンドだけを使用すると、必要な機能の95%以上が得られます)。他の低レベルのライブラリと同様に、それらをどのように組み合わせ、どのように使用するかによって、その力が得られます。最終的に、GCDやTBBなどのライブラリはまたはのようなスレッドライブラリを呼び出すことを忘れないでpthreadsくださいstd::thread
  • 時々、それはあなたが使うものではなく、あなたがそれをどのように使うかであり、それが成功か失敗かを決定します。ライブラリの支持者として、TBBまたはGCDは、ライブラリを使用することのすべての利点について説明しますが、実際のアプリケーションコンテキストでそれらを試すまでは、すべて理論上の利点があります。たとえば、きめ細かいparallel_forを使用するのがいかに簡単であるかを読んだとき、並列処理の恩恵を受けることができると思ったタスクですぐに使用しました。当然のことながら、私も、TBBが最適な負荷分散とスレッド割り当てに関するすべての詳細を処理するという事実に惹かれました。結果? TBBは、シングルスレッドバージョンの5倍の時間がかかりました。 しかし、私はTBBのせいではありません。振り返ってみると、これは明らかにparallel_forの誤用のケースです。細字部分を読んだときに、parallel_forの使用に伴うオーバーヘッドを発見し、私の場合はコンテキストのコストを推測しました。切り替えと追加された関数呼び出しは、複数のスレッドを使用する利点を上回りました。したがって、どちらがより速く実行されるかを確認するために、ケースのプロファイルを作成する必要があります。スレッドのオーバーヘッドを減らすために、アルゴリズムを再編成する必要がある場合があります。
  • なぜこれが起こるのですか?pthreadまたはスレッドなしがGCDまたはTBBよりも高速であるにはどうすればよいですか?設計者がGCDまたはTBBを設計するときは、タスクが実行される環境について想定する必要があります。実際、ライブラリは、開発者による奇妙で予期しないユースケースを処理できるように十分に一般的である必要があります。これらの一般的な実装は無料ではありません。プラス面として、ライブラリはハードウェアと現在の実行環境にクエリを実行して、負荷分散のより良い仕事をします。それはあなたの利益のために働きますか?知る唯一の方法はそれを試すことです。
  • 高レベルのライブラリが利用できる場合のように、低レベルのライブラリを学習することに何か利点std::threadはありますか?答えは確かにYESです。高レベルのライブラリを使用する利点は、実装の詳細からの抽象化です。高レベルのライブラリを使用することの欠点は、実装の詳細からの抽象化でもあります。を使用するときは、オブジェクトの共有状態と存続期間を非常によく認識しています。特に中規模から大規模のプロジェクトでは、警戒を怠ると、競合状態メモリ障害pthreadsが非常に簡単に発生する可能性があるためです。。高レベルのライブラリを使用すると、これらの問題は解消されますか?あまり。それらについて考える必要はないように思えますが、実際、それらの詳細にだらしなくなると、ライブラリの実装もクラッシュします。したがって、低レベルの構造を理解していれば、これらのライブラリはすべて実際に意味があることがわかります。低レベルの呼び出しを使用する場合は、ある時点でそれらを自分で実装することを検討するからです。もちろん、その時点では、通常、実績のあるデバッグ済みのライブラリ呼び出しを使用することをお勧めします。

それでは、可能な実装を分解してみましょう。

  • TBB / GCDライブラリの呼び出し:最大の利点は、スレッドの初心者にとってです。下位レベルのライブラリを学習する場合に比べて、参入障壁が低くなります。ただし、マルチスレッドを使用する際のトラップの一部を無視/非表示にします。動的な負荷分散により、追加のコーディングを行わなくても、アプリケーションの移植性が向上します。
  • pthreadstd::thread呼び出し:実際には、学ぶための呼び出しはほとんどありませんが、それらを正しく使用するには、アプリケーションがどのように機能するかについての詳細と深い認識に注意を払う必要があります。このレベルのスレッドを理解できれば、上位レベルのライブラリのAPIの方が確かに理にかなっています。
  • シングルスレッドアルゴリズム:単純なシングルスレッドセグメントの利点を忘れないようにしましょう。ほとんどのアプリケーションでは、マルチスレッドよりもシングルスレッドの方が理解しやすく、エラーが発生しにくくなっています。実際、多くの場合、これが適切な設計上の選択である可能性があります。実際のところ、実際のアプリケーションはさまざまなマルチスレッドフェーズとシングルスレッドフェーズを通過します。常にマルチスレッドである必要はない場合があります。

どれが最速ですか? 驚くべき真実は、それは上記の3つのいずれかである可能性があるということです。マルチスレッドの速度の利点を得るには、アルゴリズムを大幅に再編成する必要がある場合があります。メリットがコストを上回るかどうかは、ケースによって大きく異なります。

ああ、OPはthread_poolが適切でない場合について尋ねました。簡単なケース:計算にループごとに多くのサイクルを必要としないタイトなループがある場合、thread_poolを使用すると、深刻な手直しをしなくてもメリットよりもコストがかかる可能性があります。また、スレッドプールを介したラムダのような関数呼び出しのオーバーヘッドと単一のタイトループの使用に注意してください。

ほとんどのアプリケーションでは、マルチスレッドは一種の最適化であるため、適切なタイミングで適切な場所で実行してください。

于 2011-12-30T16:41:20.647 に答える
15

あなたが経験しているその圧倒的な感覚..それがまさにGCDが発明された理由です。

最も基本的なレベルにはスレッドがあります。pthreadsはスレッド用のPOSIXAPIであるため、準拠している任意のOSでコードを記述し、それが機能することを期待できます。GCDはスレッドの上に構築されています(ただし、実際にAPIとしてpthreadを使用したかどうかはわかりません)。GCDはOSXとiOSでのみ機能すると思います—一言で言えばそれが主な欠点です。

スレッドを多用し、高性能を必要とするプロジェクトは、独自のバージョンのスレッドプールを実装することに注意してください。GCDを使用すると、ホイールの再発明を何度も回避できます。

于 2010-01-27T04:57:51.063 に答える
4

openmpIntelTBBGCDのような宣言型/支援型のアプローチは、驚異的並列問題に非常に優れているはずであり、おそらくナイーブな手動のpthreadによる並列ソートを簡単に打ち負かすでしょう。ただし、まだpthreadを学ぶことをお勧めします。並行性をよりよく理解し、特定の状況ごとに適切なツールを適用できるようになります。また、pthreadベースのコードが大量に存在する場合は、「レガシー」コードを読み取ることができます。

于 2010-01-27T05:28:29.453 に答える
4

GCDはAppleテクノロジーであり、最もクロスプラットフォーム互換ではありません。pthreadは、OSX、Linux、Unix、Windowsのほぼすべてで利用できます。このトースターを含む

GCDは、スレッドプールの並列処理用に最適化されています。Pthreadは(あなたが言ったように)並列処理のための非常に複雑な構成要素であり、独自のモデルを開発する必要があります。pthreadや並列処理のさまざまなモデルについて詳しく知りたい場合は、このトピックに関する本を読むことを強くお勧めします。

于 2010-01-27T04:55:45.453 に答える
0

通常:Pthread実装ごとに1つのタスクがミューテックス(OS機能)を使用します。
GCD:キューにグループ化されたブロックごとに1つのタスク。仮想CPUごとに1つのスレッドがキューを取得し、すべてのタスクをミューテックスなしで実行できます。これにより、スレッド管理のオーバーヘッドとミューテックスのオーバーヘッドが削減され、パフォーマンスが向上します。

于 2010-09-23T19:05:34.873 に答える
0

GCDはスレッドを抽象化し、ディスパッチキューを提供します。使用可能なプロセッサコアの数を考慮して、必要と見なされるスレッドを作成します。GCDはオープンソースであり、libdispatchライブラリから入手できます。FreeBSDには、8.1以降のlibdispatchが含まれています。GCDとCブロックは、AppleからCプログラミングコミュニティへの市長の貢献です。GCDをサポートしていないOSは使用しません。

于 2013-07-15T18:42:32.443 に答える