基于OpenMP的质数并发求解方法研究

《并行程序设计》的结课论文

基于OpenMP的质数并发求解方法研究

摘要

如何快速地获得素数表以解决素数相关的复杂问题,具有重要的研究意义。给定范围内求解质数的串行算法主要有以下三种:枚举、埃氏筛、欧拉筛。本文研究给定范围内质数求解的并发性算法,基于OpenMP将枚举、埃氏筛两种串行算法并行化,并通过加速比等指标评估两种算法在不同并行方式、任务分配方式中的改进程度。

关键词

OpenMP;并行算法;筛选法

1.前言

1.1研究背景和意义

质数(Prime Number),也称素数,指一个大于1的自然数p,除了1和它本身外,不能被其他自然数整除,即不能被写成p=ab (a,b>1)的形式。质数的个数无穷。
古往今来,许多数学家和科学家致力于研究质数的相关性质和应用,提出了许多卓尔不凡的见解,但仍有许多世界难题,如哥德巴赫猜想和孪生素数猜想等。
第三次工业革命后,计算机逐渐普及,成为科学研究的重要提效工具,计算机以其极高的算力对科研的发展产生了颠覆性的影响,算法领域的发展推动了一系列数学和工程问题的解决,但时至今日,计算机科学领域仍有相当多悬而未决的难题,即非确定性多项式类问题(Non-deterministic Polynomially,NP)。对极大整数的因式分解是NP问题之一。
质数具有非常巨大的实用价值,如密码学中经典的非对称加密算法RSA算法,对极大整数做因数分解的难度决定了RSA算法的可靠性;在齿轮的设计上,相邻的两个大小齿轮齿数设计成质数,以增加两齿轮内两个相同的齿相遇啮合次数的最小公倍数,可增强耐用度,减少故障;在害虫的生物生长周期与杀虫剂使用之间的关系上,杀虫剂的质数次数的使用也得到了证明等等。
如何快速地在计算机中获得素数表以解决素数相关的复杂问题,具有重要的研究意义。

1.2研究问题和研究方法

在给定范围内求解质数的串行算法主要有以下三种:枚举、埃氏筛、欧拉筛(也称线性筛)。针对极大整数的判断可通过素性检测,常见素性检测算法有费马素性检验(Fermat primality test),米勒拉宾测试(Miller–Rabin primality test)等,但素性测试是概率测试,不能给出100%正确结果。[1]
本文研究的问题是给定范围内质数求解的并发性算法,基于OpenMP将枚举、埃氏筛两种串行算法并行化,并通过加速比等指标评估算法的改进程度。

2.枚举法

2.1设计思想

判断正整数x是否为素数,只需判断x%i=0(i∈[2,x-1])是否成立,若x对任意i都不能整除,则x是素数。
若x%k=0(k∈[2,√x]),则必然存在s∈[√x,n-1]使得 x%s=0,也就是说,当x有一个小于√x的因数,则必然有一个大于等于√x的因数与之相乘乘积为x。基于这个思想,可以改进最朴素的枚举法,减少枚举次数,改进后的枚举法的for循环最多只需判断[2,√x]次,算法时间复杂度为O(n*√n).
在串行的枚举法基础上修改得到并行枚举算法,将n次判断分配给thread_count个线程并行处理,在修改prime2数组时需进行临界区保护。
随着x的增大,isPrime函数的负载增加,将任务按照顺序分块给不同线程有悖负载均衡的原则,故采用不同的分配方式分配并行任务给线程:默认分配方式、静态(static)循环分配方式、动态(dynamic)循环分配方式、动态(guided)循环分配方式。运行代码,分析加速比。

2.2运行结果

线程数=4

分配方式 默认分配 static(size=5) dynamic(size=5) guided(size=5)
串行时间(ms) 10188 10046 9999 10198
并行时间(ms) 3584 2742 2612 2700
加速比 2.84 3.66 3.83 3.78

线程数=8

分配方式 默认分配 static(size=5) dynamic(size=5) guided(size=5)
串行时间(ms) 10022 10060 10100 9918
并行时间(ms) 2147 1878 1823 1868
加速比 4.67 5.36 5.54 5.31

2.3结果分析

并行程序相对串行程序有显著的速度提升,4线程并行程序在dynamic分配方式下加速比更是达到了3.83,接近于最高加速比4。
观察结果发现,默认分配方式加速比显著低于循环分配方式,可见负载均衡对提升并行程序加速比有显著作用,但动态循环分配方式相较静态循环分配方式提升不多,guided动态循环分配方式加速比甚至低于dynamic动态循环分配方式,可见动态循环分配方式给算法增加了额外开销,且其效率的增加无法抵消运算分配这一额外开销的副作用。
由结果分析得出,dynamic动态循环分配方式权衡了效率的增加与运算分配任务的开销,是目前加速比最高的算法。

2.4程序源码

见7.1.1枚举法并行化源码

3.埃氏筛算法

3.1设计思想

埃拉托斯特尼算法,公元前250年由希腊数学家埃拉托斯特尼提出,简称埃氏筛,其基本思想是:求解给定范围0到正整数n内的全部质数,将不大于√n的所有质数的倍数筛去,剩下的即为所得结果。[2]
算法步骤如下:

  1. 将[2,n-1]全部标记为质数

  2. 取出第一个质数p

  3. 将质数p在n内的倍数全部标记为非质数

  4. 根据标记信息,取下一个质数p,判断p^2是否大于n,若是,算法结束,若不是,返回③

我们还可以继续改进这一算法,将质数在n内的倍数全部标记为非质数时,由于部分倍数已经被更小的质数在之前标记过,因此筛选的起点设为p^2,步长为2p。埃式筛的算法时间复杂度为O(n*log⁡(logn))).
由于埃式筛的时间复杂度较低,用与枚举法相同的数据量1e7已无法准确评估算法效率的提升,因此增大N至1e8运行。
将串行算法并行化,由于质数的取数具有循环依赖,因此外层循环无法并行,但内层目的为标记合数的循环没有循环依赖,可以并行。运行代码,分析加速比。

3.2运行结果

N=1e7

线程数 4 6 8
串行时间(ms) 52 41 55
并行时间(ms) 49 48 70
加速比 1.06 0.85 0.79

N=1e8

线程数 4 6 8
串行时间(ms) 1275 1189 1205
并行时间(ms) 733 831 841
加速比 1.74 1.43 1.43

3.3结果分析

由运行结果可见,N=1e8时多线程时加速比较高,但线程增加时加速比反而降低;N=1e7时六线程、八线程并行反而比串行运行速度更慢,考虑原因为计算量较小时,线程增加导致并行创建线程、合并线程的开销增大,这一副作用带来的时间花费远高于并行带来的效率增加,导致程序性能没有提升反而下降。可见仅当计算量高时,考虑并行程序有其实际意义。

3.4程序源码

见7.1.2埃式筛并行化源码

4.欧拉筛算法

4.1设计思想

埃式筛的算法时间复杂度在n较大时已经非常接近O(n),但欧拉筛更进一步,拥有线性的时间复杂度,即O(n),而且编码较为简单,应用十分广泛。
假设要筛出n以内的素数,算法步骤如下:

  1. 将[2,n-1]全部标记为质数
  2. 取出第一个质数p
  3. 将p加入素数表,cnt++
  4. 枚举已经筛出的素数prime[j] ,j∈[0,cnt),标记p * prime[j]为合数,当p为prime[j]的倍数时退出循环。
  5. 取出下一个素数p,若p>=n,结束算法;若不是,返回③

由于质数的取数具有循环依赖,因此外层循环无法并行;而内层由于欧拉筛有退出循环的break机制,因此无法将之for循环并行化。

4.2运行结果

N=1e8, serial time=883ms

4.3结果分析

相较于埃式筛,欧拉筛更加高效,时间复杂度达到了完全的O(n),效率已经得到了明显提升。由于其高效性,并行化具有较小的改进意义。

4.4程序源码

见7.1.3欧拉筛源码

5.结论

枚举法的算法时间复杂度为O(n*√n),埃式筛的算法时间复杂度为O(n*log⁡(logn))),欧拉筛的算法时间复杂度为O(n)。其中,欧拉筛因为时间复杂度较低,并行化带来的收益不明显,串行程序便可很好地完成筛选素数的工作;枚举法通过并行化与负载均衡改进,效率可得到明显改善,当八线程时,加速比可达到5.5;埃式筛在计算量较高时,通过并行化可提升算法效率,四线程加速比可达1.74。

6.参考文献

[1]质数[EB/OL].(2012-12-19)[2023-07-20].https://baike.baidu.com/item/%E8%B4%A8%E6%95%B0/263515

[2]moqikaiv.埃拉托斯特尼筛法[EB/OL].(2017-06-23)[2023-07-20].https://blog.csdn.net/moqikaiv/article/details/73614397

7.附录:

7.1程序源码

7.1.1枚举法并行化源码

#include
#include
#include

你可能感兴趣的:(并行程序设计,OpenMP,并行程序设计)