在嵌套循环中使用 OpenMP 的性能问题
Performance problems using OpenMP in nested loops
我正在使用以下代码,其中包含嵌套在另一个 for 循环中的 OpenMP 并行 for 循环。这段代码的性能不知何故比顺序版本慢 4 倍(省略#pragma omp parallel for)。
有没有可能每次调用方法时OpenMp都要创建Threads?在我的测试中它被直接调用了10000次。
我听说有时 OpenMP 会使线程保持旋转。我还尝试设置 OMP_WAIT_POLICY=active
和 GOMP_SPINCOUNT=INFINITE
。当我删除 openMP pragmas 时,代码速度大约快 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
) .在这种情况下,最好将 parallel
与 for
分开,这样分叉和创建线程的工作只完成一次,而不是在其他循环中重复。因此,您可以尝试在最外层循环之前放置一个 parallel
编译指示,这样分叉和线程创建的开销就只完成一次。
实际问题与 OpenMP 没有直接关系。
由于系统有两个 CPU,一半的线程在一个上生成,另一半在另一个 CPU 上生成。因此没有共享的 L3 缓存。这导致算法不能很好地扩展到性能下降的组合,尤其是在使用 2-4 个线程时。
解决方案是通过 linux 工具使用螺纹固定:taskset
我正在使用以下代码,其中包含嵌套在另一个 for 循环中的 OpenMP 并行 for 循环。这段代码的性能不知何故比顺序版本慢 4 倍(省略#pragma omp parallel for)。
有没有可能每次调用方法时OpenMp都要创建Threads?在我的测试中它被直接调用了10000次。
我听说有时 OpenMP 会使线程保持旋转。我还尝试设置 OMP_WAIT_POLICY=active
和 GOMP_SPINCOUNT=INFINITE
。当我删除 openMP pragmas 时,代码速度大约快 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
) .在这种情况下,最好将 parallel
与 for
分开,这样分叉和创建线程的工作只完成一次,而不是在其他循环中重复。因此,您可以尝试在最外层循环之前放置一个 parallel
编译指示,这样分叉和线程创建的开销就只完成一次。
实际问题与 OpenMP 没有直接关系。
由于系统有两个 CPU,一半的线程在一个上生成,另一半在另一个 CPU 上生成。因此没有共享的 L3 缓存。这导致算法不能很好地扩展到性能下降的组合,尤其是在使用 2-4 个线程时。
解决方案是通过 linux 工具使用螺纹固定:taskset