算术数计算问题中的这个循环可以并行化吗?

Can this loop in the Arithmetic Numbers Calculation Problem be parallelised?

提问人:Pavle Šarenac 提问时间:11/7/2023 最后编辑:Pavle Šarenac 更新时间:11/8/2023 访问量:79

问:

我认为 和 变量可能是外循环潜在并行化中线程的减少变量。我只是有点困惑这种并行化是否真的是可能的,因为在内部循环中正在发生变化,那么这是否意味着外部循环的迭代是相互依赖的,并且由于这个原因并行化是不可能的?divisor_countdivisor_sumn

unsigned int divisor_count = 1;
unsigned int divisor_sum = 1;
unsigned int power;
for (unsigned int p = 3; p * p <= n; p += 2)
{
    unsigned int count = 1, sum = 1;
    for (power = p; n % p == 0; power *= p, n /= p)
    {
        ++count;
        sum += power;
    }
    divisor_count *= count;
    divisor_sum *= sum;
}
C 并行处理 OpenMP

评论

0赞 Victor Eijkhout 11/7/2023
在质数上创建外循环,并给每次迭代一个副本。事实上,不,这不能并行化。n
0赞 Pavle Šarenac 11/7/2023
你能修改代码并将其粘贴到这里吗,我不确定我是否理解你。感谢您的快速回复!另外,我说得对吗,由于 n 的变化,无法并行化的原因是否是迭代之间的数据依赖性?
1赞 paleonix 11/7/2023
基本上是的,参见 Canonical Loop Form。循环的范围需要在开始时完全确定。parallel for
0赞 Victor Eijkhout 11/7/2023
@paleonix : OpenMP 的外循环格式良好。问题在于除以 的因子对数据的依赖性。但是,如果每个值都有自己的副本,那么一切都会成功。我认为。npnfirstprivate
0赞 Victor Eijkhout 11/7/2023
@PavleŠarenac 你为什么不开始编写 OpenMP 指令,然后我可能会给出建议。

答:

1赞 Jim Cownie 11/8/2023 #1

假设你的意思是这篇维基百科文章意义上的“算术数”,你的整个计算在我看来是可疑的。

这是一个简单的 Python 代码,用于检查数字是否为算术。转换为 C/C++ 和并行化应该是微不足道的。

import math

def isArithmetic(n):
    divisorSum = 1+n
    divisorCount = 2
    ub = math.ceil(math.sqrt(n))

    # Handle the square case outside the loop, since
    # the square root only counts as one factor.
    if (ub*ub == n):
        divisorSum += ub
        divisorCount += 1
    # Find all the other pairs of factors
    for i in range(2,ub):
        if (n % i) == 0:
            divisorSum += i + n/i
            divisorCount += 2

    return (divisorSum % divisorCount) == 0

arithmeticNumbers = [i for i in range(1,50) if isArithmetic(i)]

print (arithmeticNumbers)

这给出了与文章相同的集合。不过,我怀疑你会得到很多性能提升,因为循环中的工作相当小。

(我把剩下的留给你了,因为我不想为你做所有的功课:-))。