在嵌套循环中使用OpenMP的性能问题

时间:2015-02-12 18:55:59

标签: c++ multithreading openmp

我使用以下代码,其中包含一个嵌套在另一个for循环中的OpenMP并行for循环。不知何故,这段代码的性能比顺序版慢4倍(省略#pragma omp parallel for)。

每次调用方法时OpenMp都有可能创建线程吗?在我的测试中,它直接被称为10000次。

我听说OpenMP会让线程保持旋转状态。我还尝试设置OMP_WAIT_POLICY=activeGOMP_SPINCOUNT=INFINITE。当我删除openMP pragma时,代码大约快10倍。请注意,包含此代码的方法将被调用10000次。

        for (round k = 1; k < processor.max; ++k) {
            initialise_round(k);


            for (std::vector<int> bucket : color_buckets) {
                #pragma omp parallel for schedule (dynamic)
                for (int i = 0; i < bucket.size(); ++i) {
                    if (processor.mark.is_marked_item(bucket[i])) {
                        processor.process(k, bucket[i]);
                    }
                }
            processor.finish_round(k);
        }
    }

3 个答案:

答案 0 :(得分:2)

你说你的顺序代码要快得多,所以这让我认为你的processor.process函数的指令和持续时间太少了。这导致将数据传递到每个线程的情况不会得到回报(数据交换开销仅比该线程上的实际计算大)。

除此之外,我认为并行化中间循环不会影响算法,但会增加每个线程的工作量/

答案 1 :(得分:0)

我认为你是在循环的每次迭代中创建一个线程团队......(虽然我不确定for单独做什么 - 我认为它应该是parallel for)。在这种情况下,将parallelfor分开可能会更好,因此分叉和创建线程的工作只需执行一次,而不是在其他循环中重复。因此,您可以尝试在最外层循环之前放置parallel pragma,这样就可以完成分叉和创建线程的开销一次。

答案 2 :(得分:0)

实际问题与OpenMP没有直接关系。

由于系统有两个CPU,一半的线程在另一个CPU上生成,另一半在另一个CPU上生成。因此没有共享L3缓存。这导致该算法无法很好地扩展到性能下降,尤其是在使用2-4个线程时。

解决方案是使用线程固定,例如通过linux工具:taskset

相关问题