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

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

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

我听说有时OpenMP会保持线程旋转。 我也尝试设置OMP_WAIT_POLICY=activeGOMP_SPINCOUNT=INFINITE 。 当我删除openMP编译指示时,代码快了大约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);
        }
    }

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

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


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


实际问题与OpenMP直接无关。

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

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

链接地址: http://www.djcxy.com/p/13903.html

上一篇: Performance problems using OpenMP in nested loops

下一篇: OpenMP: sharing arrays between threads