首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程构建块中嵌套循环的并行化

线程构建块中嵌套循环的并行化
EN

Stack Overflow用户
提问于 2011-04-02 15:55:12
回答 2查看 959关注 0票数 1

我对线程化构建块和尝试在TBB中编码FFT算法是新手,以获得一些实践经验。在这个算法中,我只能并行化最里面的循环。但是通过这样做,性能已经下降到不可接受的程度(超过1000次)。我曾尝试将数组大小设置为2^20,但结果相同。我的代码如下所示

代码语言:javascript
复制
for(stage1=0;stage1 < lim;stage1 ++)
{
    butterfly_index1 = butterfly_index2;
    butterfly_index2 = butterfly_index2 + butterfly_index2; 
    k = -1*2*PI/butterfly_index2;
    k_next = 0.0;
    for(stage2 = 0 ; stage2 < butterfly_index1;stage2++)
    {
        sine=sin(k_next);
        cosine = cos(k_next);
        k_next = k_next + k;
        FFT. sine = &sine;
        FFT.cosine = &cosine;
        FFT.n2 = &butterfly_index2;
        FFT.loop_init = &stage2;
        FFT.n1 = &butterfly_index1;
        parallel_for(blocked_range<int>(
                        stage2,SIZE,SIZE/4),FFT,simple_partitioner()); 
    }
}   

parallel_loop的主体是

代码语言:javascript
复制
void operator()(const blocked_range<int> &r)const
{
    for(int k = r.begin(); k != r.end(); k++)
    {   
        if(k != *loop_init)
        {
            if((k - (*loop_init))% (* n2)!= 0)
                continue;
        }           
        temp_real = (*cosine) * X[k + *n1].real - (*sine) * X[k + *n1].img;
        temp_img = (*sine)* X[k + *n1].real + (*cosine) * X[k + *n1].img;
        X[k + *n1].real = X[k].real - temp_real;
        X[k + *n1].img = X[k].img - temp_img;
        X[k].real = X[k].real + temp_real;
        X[k].img = X[k].img + temp_img; 
    }
}

如果我用普通循环替换它,那么一切都是正确的。

EN

回答 2

Stack Overflow用户

发布于 2011-04-03 17:36:34

对于非常短的工作负载,由于线程创建的开销,可能会发生巨大的减慢。对于数组中的2^20个元素,我不相信会发生如此巨大的性能下降。

性能下降的另一个重要原因是编译器无法在代码被TBBfied之后对其进行优化(特别是向量化)。了解您的编译器是否可以生成矢量化报告,并查找串行版本和TBB版本之间的差异。

一个可能的减慢来源可能是parallel_for的body类的复制构造函数,因为body被复制了很多次。但是给定的代码在这方面看起来并不可疑:似乎主体包含一些指针。无论如何,看看这是否会成为一个问题。

另一个常见的重要开销来源是太细粒度的并行,即许多任务,每个任务只包含很少的工作。但这里也不是这样,因为blocked_range的第三个参数中的grainsize SIZE/4指定body的运算符()()在每个算法中最多被调用4次。

我建议不要在初始实验中指定simple_partitioner和grainsize,而是让TBB动态分发工作。如果需要,您可以在以后对其进行调整。

票数 1
EN

Stack Overflow用户

发布于 2011-04-04 05:23:59

我的代码的问题是,随着n2变量的增加,工作负载减少了。因此,随着外循环的进行,parallel_for的工作负载将减半,并且在几次迭代之后,它变得太小,无法通过使用TBB来提高性能。因此,解决方案是只在内循环的工作负载足够时才对内循环进行并行化,而对于其余的迭代则对内循环进行序列化。其次,包含条件检查(k != r.end())的"for“循环头也会降低性能。解决方案是用初始化为r.end()的本地定义变量替换r.end()

感谢英特尔软件论坛对解决此问题的帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5521954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档