如何在while循环中使用OpenMP并在其中添加break语句

3
我希望使用OpenMP来加速下面这段代码。
这段代码只是为了说明操作,不是真实的。
Iterator iterator(records);
while(iterator.next())
{
    int current_id = iterator.current_row_index();
    bool result = index.find(records[current_id])
    if (result == false)
        if (index.insert(records[current_id]) == false)
            break;
}
return iterator.current_row_index();

索引被所有线程共享。

以下是我的一些想法:

  • 使用omp并行指令确保线程按顺序运行。
  • 使用omp关键指令来操作迭代器。
  • 使用omp关键指令查找索引并插入索引。

但我真的怀疑速度提升,因为几乎所有操作都在关键区域内。

有没有一些建议可以使用openmp加速代码?

谢谢!


迭代器只是前向迭代器吗?它能用作随机访问迭代器吗? - Anton
@Anton,现在它只是一个前向迭代器,但我可以修改它以支持后向迭代,但它不能是随机访问的。而且我更喜欢不修改迭代器代码。 - b8flowerfire
你是想停在串行循环中找到的第一个索引还是任意索引? - Walter
@Walter 我想第一次就停止。因为我们需要中断索引来返回。 - b8flowerfire
1个回答

4
假设没有其他问题(下面会讨论),回答问题标题,一个带有中断条件的通用 while 循环可以翻译成这样:
Iterator iterator(records);
#pragma omp parallel
{
    #pragma omp single nowait
    {
        while(iterator.next())
        {
            int current_id = iterator.current_row_index();
            #pragma omp task firstprivate(current_id)
            {
                if ( should_stop(current_id)) ) {
                    // below requires OpenMP 4.0
                    #pragma omp cancel parallel
                }
            }
        }
    }
}

然而,您的问题中还有更复杂的问题,实际上值得单独提出问题。

  1. 使用index表表明它不是线程安全的。因此,您不能同时安全地访问和插入。而且,由于它是while循环的唯一工作,除非您切换到像, , 提供的并发哈希表concurrent_unordered_map,否则没有意义将其并行化。

  2. 不清楚何时插入会返回false以及为什么需要在发生这种情况时知道行的索引。可能,在切换到另一个表实现之后,这将完全是不必要的。否则,通常有几个线程可以同时对您的条件做出“答案”,您必须同步它们并将其缩小为单个结果。最简单的OMP方式是使用关键段来选择和存储结果,否则程序可能会出现竞争条件的危险。


current_id 应该改为 firstprivate - Hristo Iliev
1
您也可以完全省略该子句,因为在task构造中使用时,private变量默认为firstprivate - Hristo Iliev
非常感谢。我正在使用OpenMP加速超音速源代码(Google开源查询引擎项目)。这是哈希连接操作中的构建阶段。我认为我应该查看更多相关代码来解决这个问题。非常感谢您的帮助。 - b8flowerfire
G++拒绝使用#pragma: "error: ‘#pragma omp cancel parallel’ construct not closely nested inside of ‘#pragma omp parallel’". 我最终不得不在我的任务主体周围加上if (!finished) {...}; 我无法让while (!finish && ...)停止迭代。 - Toby Speight
@toby 这个结构需要使用OMP 4.0。 - Anton
啊,我以为更新的版本也会有它。顺便说一下,cpp -fopenmp -dM /dev/null |grep -i open 报告 #define _OPENMP 201511,这似乎意味着 OpenMP 4.5。 - Toby Speight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接