1

サンプルコードは次のとおりです。

#include <iostream>
#include <list>
#include <tbb/task.h>
#include <tbb/task_group.h>
#include <stdlib.h>
#include <boost/thread.hpp>

using namespace tbb;

 long fib(long a)
{
  if (a < 2) return 1;

  return fib(a - 1) + fib(a - 2);
}

class PrintTask 
{
public:
    void operator()()
    {
        std::cout << "hi world!: " <<  boost::this_thread::get_id() << std::endl;

        fib(50);
    }
};

int main(int argc, char** argv)
{     
    task_group group;

    for (int i = 0; i < 100; ++i)
    {
      group.run(PrintTask());
    }      

    group.wait();

    return(0);
}

ここでは、ノンブロッキング計算をシミュレートするためだけに大きなフィボナッチ数列を計算しています。このコードが3つ以上のスレッドを生成することを期待していました(私のコンピューターはCore2Duoです)が、最初と2番目のタスクのみが呼び出されます。これは見物ですか?

4

2 に答える 2

4

はい、これは予想される動作です。

TBB は、パフォーマンスのためにコードを並列化するために設計されたライブラリです。非同期タスク用に設計されていません。公式ドキュメントでは、そのようなタスクには pthreads などの別のライブラリを使用する必要があると記載されています (または、boost::thread の場合)。

最大のパフォーマンスを得るために、コアよりも多くのスレッドを使用しても意味がありません。これは、いくつかの重要なオーバーヘッド (コンテキストの切り替えだけでなく、キャッシュのフラッシュなど) が関係しているためです。

編集:チュートリアルでそれについて読むことができます。具体的には、セクション1.2の「利点」に記載されています

インテル® スレッディング・ビルディング・ブロックは、パフォーマンスのためにスレッド化をターゲットにしています。ほとんどの汎用スレッド パッケージは、グラフィカル ユーザー インターフェイスでの非同期イベントのスレッド化など、さまざまな種類のスレッド化をサポートしています。その結果、汎用パッケージは、ソリューションではなく、基盤を提供する低レベルのツールになる傾向があります。代わりに、インテル® スレッディング・ビルディング・ブロックは、計算集約型の作業を並列化するという特定の目標に焦点を当て、より高度でシンプルなソリューションを提供します。

インテル® スレッディング・ビルディング・ブロックは、他のスレッディング・パッケージと互換性があります。ライブラリはすべてのスレッド化の問題に対処するようには設計されていないため、他のスレッド化パッケージとシームレスに共存できます。

于 2010-11-22T16:25:57.823 に答える
1

大規模なマルチスレッドのブロック動作 (std::cout の使用) は、マルチスレッドのアンチパターンであり、不適切な動作になる可能性があります。さらに、TBB は group.run() を実装する権利を留保します。デュアル コアしかなく、負荷の高い呼び出しを行う場合、なぜ 2 つ以上のスレッドを生成する必要があるのでしょうか? OS や他のアプリは残りのバックグラウンド時間を喜んで食い尽くします。

于 2010-08-03T13:21:56.257 に答える