将 do/while 转换为并行 do/while 循环

Convert do/while into parallel do/while loop

我在将 do/while{} 转换为 OpenMP 时遇到问题。我正在关注来自康奈尔大学虚拟研讨会的 Example: While Loop

这里是原文do/while{}。变量 rremodn 只是 Crypto++ 类。 rreIntegers, while modn is a ModularArithmeticRandomize 创建指定范围内的整数。

do {
    r.Randomize(rng, Integer::One(), m_n - Integer::One(), Integer::ANY);
    rInv = modn.MultiplicativeInverse(r);
} while (rInv.IsZero() || (Jacobi(r % m_p, m_p) == -1) || (Jacobi(r % m_q, m_q) == -1));

可并行化的部分是生成随机数后的两次雅可比检验。雅可比 (O(m·log(n))) 比模反演 (O( n^2)).此外,Jacobi 有 75% 的时间会失败,因此我应该在进行模反演之前执行 Jacobi 检验。

这是我翻译成的。 编辑:删除了外部 #pragma omp parallel private(stop) { ... }。如果kfsone的回答没有意义,请查看历史。

bool stop = false;
while(!stop)
{
    r.Randomize(rng, Integer::One(), m_n - Integer::One());        

    int jp, jq;
    #pragma omp parallel sections
    {
        #pragma omp section
            jp = Jacobi(r % m_p, m_p);
        #pragma omp section
            jq = Jacobi(r % m_q, m_q);
    }

    if ((jp != -1) && (jq != -1))
    {
        rInv = modn.MultiplicativeInverse(r);

        if(rInv.NotZero()) {
            stop = true;
        }
    }
}

非OMP版本自检成功,OMP版本自检失败,所以我知道有问题。

我在 do/while{} 的 OMP 版本中做错了什么?

private(stop) 告诉 omp 给每个线程一个唯一的 stop 实例,而不是共享一个公共值。

https://msdn.microsoft.com/en-us/library/c3dabskb.aspx

删除它或将其明确指定为共享。