什么是并行计算?如何用Python进行并行计算(48)

小朋友们好,大朋友们好!

我是猫妹,一名爱上Python编程的小学生。

和猫妹学Python,一起趣味学编程。

今日主题

什么是并行计算?

如何用验证10万之内的数是符合哥德巴赫猜想的?

并行计算

什么是并行计算

并行计算是指同时执行多个任务或计算,以提高计算速度和效率。

在个人电脑中,多核处理器可以同时处理多个任务,从而实现并行计算。

假设我们需要对一个大型数据集进行排序。

传统的计算方法是使用一个循环来遍历整个数据集,然后按照一定的规则进行排序。

但是,如果数据集很大,这个过程可能需要很长时间才能完成。

在并行计算中,我们可以将数据集分成多个部分,然后让不同的核心同时处理这些部分。

这样,每个核心都可以独立地进行排序,从而加快整个过程的速度。

总之,并行计算是一种通过同时执行多个任务来提高计算效率的技术。

在个人电脑中,多核处理器的并行计算可以帮助我们更快地完成各种计算任务。

multiprocessing库

multiprocessing库

多进程 Multiprocessing 和多线程 threading 类似, 他们都是在 python 中用来并行运算的.

有了 threading, 为什么 还要有 multiprocessing 呢?

很简单, 就是用来弥补 threading 的一些劣势, 比如在 threading 教程中提到的GIL。

使用 multiprocessing 非常简单, 如果对 threading 有一定了解的朋友, 你们的享受时间就到了。

因为 python 把 multiprocessing 和 threading 的使用方法做得几乎差不多。

查看CPU物理核心数

multiprocessing中的函数cpu_count可以返回当前CPU的核数。

猫妹的CPU是8核的。

time.perf_counter()

perf_counter()是第三方库time的函数。

perf_counter()返回当前的计算机系统时间。

只有连续两次perf_counter()进行差值才能有意义,一般用于计算程序运行时间。

Pool类

在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量的时间。

如果操作的对象数目不大时,还可以直接使用Process类动态的生成多个进程,十几个还好,但是如果上百个甚至更多,那手动去限制进程数量就显得特别的繁琐,此时进程池就派上用场了。

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。

如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。

Pool类map()函数原型:

map(func, iterable[, chunksize=None])

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。

注意,虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。

Pool类close()函数

关闭进程池(pool),使其不再接受新的任务。

Pool类join()函数

主进程阻塞等待子进程的退出,join方法必须在close或terminate之后使用。

举个例子

import time
from multiprocessing import Pool


def run(fn):
  #fn: 函数参数是数据列表的一个元素
  time.sleep(1)
  return fn*fn


if __name__ == "__main__":
  testFL = [1,2,3,4,5,6]
  
  print('顺序:') #顺序执行(也就是串行执行,单进程)
  s = time.time()
  for fn in testFL:
    run(fn)
  e1 = time.time()
  print("顺序执行时间:", int(e1 - s))


  print('\nconcurrent:') #创建多个进程,并行执行
  pool = Pool(5)  #创建拥有5个进程数量的进程池
  #testFL:要处理的数据列表,run:处理testFL列表中数据的函数
  rl =pool.map(run, testFL) 
  pool.close()#关闭进程池,不再接受新的进程
  pool.join()#主进程阻塞等待子进程的退出
  e2 = time.time()
  print("并行执行时间:", int(e2-e1))
  print(rl)

用Python验证10万~100万的数符合哥德巴赫猜想

我们根据电脑先拿到CPU的物理核心数,然后将10万之内的数平均分别几份,每个CPU物理核分配一段数据空间,验证分配其数字符合哥德巴赫猜想。

测试代码:

#多进程验证哥德巴赫猜想
import time
from  multiprocessing import cpu_count
from multiprocessing import Pool
from Goldbach import goldbach


#把数字空间N分段,分段数为内核数
def subRanges(N, CPU_COUNT):
    list = [[i + 1, i + N // CPU_COUNT] for i in range(4, N, N // CPU_COUNT)]
    list[0][0] = 4
    if list[CPU_COUNT - 1][1] > N:
        list[CPU_COUNT - 1][1] = N
    return list


def main():
    N = 10**6       #根据电脑性能调整
    CPU_COUNT = cpu_count()  #获取CPU内核数
    print("物理机的CPU核心数:",CPU_COUNT)
    
    sepList = subRanges(N, CPU_COUNT)   #将数N按内核数分割
    print(sepList)
    
    #单进程测试
    print("单进程")
    start = time.perf_counter()
    results=goldbach([4, N])    #4-N区间内执行goldbach
    for sample in results:
        print('%d=%d+%d' % sample)
    print('单进程耗时:%d s' % (time.perf_counter() - start))


    #多进程测试
    print("多进程")    
    pool = Pool(CPU_COUNT)   #建立进程池,进程数等于CPU内核数
    sepList = subRanges(N, CPU_COUNT)   #将数N按内核数分割
    start = time.perf_counter()
    results=pool.map(goldbach, sepList)    #并行迭代goldbach函数
    pool.close()    #关闭进程池
    pool.join()     #等待所有进程结束


    for result in results:
        for sample in result:
            print('%d=%d+%d' % sample)
    print('多进程耗时:%d s' % (time.perf_counter() - start))


if __name__ == '__main__':
    main()

模块Goldbach内容可以看和猫妹学Python的上一篇文章,因为数据量比较大,可以只关心10万的整数,比如10万~100万。

                    if i % 100000 == 0:  # 每隔10万输出样例
                        sample.append((i,j,k))

测试运行结果:

看同名公众号吧,这里的图片传不上去,有点无语

好了,我们今天就学到这里吧!

如果遇到什么问题,咱们多多交流,共同解决。

我是猫妹,咱们下次见!

猜你喜欢

转载自blog.csdn.net/parasoft/article/details/130905741
今日推荐