英特尔TBB与升压

时间:2011-08-20 06:00:09

标签: boost boost-thread tbb

我的新应用程序我可以灵活地决定使用库进行多线程处理。到目前为止我一直在使用pthread。现在想探索跨平台库。我对TBB和Boost不感兴趣。我不明白TBB比Boost有什么好处。 我试图找出TBB优于Boost的优势: TBB摘录wiki“相反,图书馆通过允许将操作视为”任务“来抽象对多个处理器的访问,这些任务由库的运行时引擎动态分配给各个核心,并自动有效地使用缓存。 TBB程序根据算法创建,同步和销毁相关任务的图形,“

但是线程库甚至需要担心线程分配到核心。这不是操作系统的工作吗? 那么使用TBB而不是Boost的真正优势是什么?

2 个答案:

答案 0 :(得分:34)

  

但是线程库甚至需要担心线程分配到核心。这不是一个操作系统的工作?那么使用TBB而不是Boost的真正优势是什么?

你是对的,线程库通常不应该关心将线程映射到核心。 TBB没有。 TBB以任务而非线程运行。 TBB的调度程序通过分配一个线程池并让它动态选择要运行的任务来利用所有核心。这是优于Boost的主要优势,您需要手动将可用工作映射到线程。然后TBB提供高级构造,例如parallel_for,parallel_pipeline等,可用于表达最常见的并行模式,并隐藏所有操作与任务。

例如,让我们用一段代码来计算Mandelbrot分形点(取自http://warp.povusers.org/Mandelbrot/,省略变量初始化):

for(unsigned y=0; y<ImageHeight; ++y)
{
    double c_im = MaxIm - y*Im_factor;
    for(unsigned x=0; x<ImageWidth; ++x)
    {
        double c_re = MinRe + x*Re_factor;

        double Z_re = c_re, Z_im = c_im;
        bool isInside = true;
        for(unsigned n=0; n<MaxIterations; ++n)
        {
            double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
            if(Z_re2 + Z_im2 > 4)
            {
                isInside = false;
                break;
            }
            Z_im = 2*Z_re*Z_im + c_im;
            Z_re = Z_re2 - Z_im2 + c_re;
        }
        if(isInside) { putpixel(x, y); }
    }
}

现在要使它与TBB并行,你只需要将最外层的循环转换为tbb :: parallel_for(为简洁起见我使用C ++ 11 lambda):

tbb::parallel_for(0, ImageHeight, [=](unsigned y)
{
    // the rest of code is exactly the same
    double c_im = MaxIm - y*Im_factor;
    for(unsigned x=0; x<ImageWidth; ++x)
    {
        ...
        // if putpixel() is not thread safe, a lock might be needed
        if(isInside) { putpixel(x, y); }
    }
});

TBB将自动分配可用内核上的所有循环迭代(并且您不会打扰多少)并动态平衡负载,这样如果某个线程有更多的工作要做,其他线程不只是等待它,而是帮助,最大化CPU利用率。尝试用原始线程实现它,你会感觉到区别:)

答案 1 :(得分:9)

英特尔TBB引入了自己的线程池/调度程序和执行模型(包括parallel_for构造之类的东西),而Boost只有基本的线程管理功能(创建线程和同步原语,即&#39;使用Boost编写一个好的线程池是可能的,但很难--TBB已经提供了一个高度优化的线程池。所以它完全取决于您的要求:如果您只需要便携式pthreads&#34;,请使用Boost,如果您需要更多,请使用英特尔TBB。