好吧,让我们走吧!
>
钥匙要点>平行和串行计算
想象您有一个巨大的问题要解决,您一个人。您需要计算八个不同数字的平方根。你做什么工作?好吧,您没有很多选择。您从第一个数字开始,然后计算结果。然后,您继续与其他人一起。
>如果您有三个擅长帮助您的数学擅长的朋友怎么办?他们每个人都会计算两个数字的平方根,并且您的工作将更容易,因为工作负载平均分布在您的朋友之间。这意味着您的问题将被更快地解决。
>好吧,这一切都很清楚吗?在这些示例中,每个朋友代表CPU的核心。在第一个示例中,整个任务由您顺序解决。这称为串行计算。在第二个示例中,由于您总共使用四个内核,因此您正在使用并行计算。并行计算涉及处理器中多个内核之间的并行过程或过程的使用。
>
我们已经建立了什么是平行编程,但是我们如何使用它?好吧,我们在该并行计算之前说过,涉及处理器多个内核之间的多个任务,这意味着这些任务是同时执行的。在接近并行化之前,您应该考虑一些问题。例如,还有其他优化可以加快我们的计算吗?
>目前,让我们理所当然地认为并行化是您的最佳解决方案。并行计算中主要有三个模型:
>
>您可能听说过其他库,例如螺纹,这些库也与Python一起内置,但是它们之间存在着重要的差异。多处理模块会创建新的过程,而线程创建新线程。使用多处理
的好处以下是多处理的一些好处:
多处理的第三个优点是,鉴于您要处理的任务非常适合并行编程。
开始使用Python多处理我们终于准备好编写一些Python代码!
>
我们将从一个非常基本的示例开始,我们将使用它来说明Python多处理的核心方面。在此示例中,我们将有两个进程:父程进程。只有一个父程流程可以有多个孩子。
儿童过程。这是由父母产生的。每个孩子也可以有新孩子。
在此片段中,我们定义了一个称为Bubble_Sort(数组)的函数。此功能是气泡排序算法的真正幼稚实现。如果您不知道它是什么,请不要担心,因为这并不重要。要知道的至关重要的是,这是一个有效的函数。
>>从多处理中,我们导入类过程。该类代表将在单独的过程中运行的活动。确实,您可以看到我们已经通过了一些论点:
<span>from multiprocessing import Process </span> <span>def bubble_sort(array): </span> check <span>= True </span> <span>while check == True: </span> check <span>= False </span> <span>for i in range(0, len(array)-1): </span> <span>if array[i] > array[i+1]: </span> check <span>= True </span> temp <span>= array[i] </span> array<span>[i] = array[i+1] </span> array<span>[i+1] = temp </span> <span>print("Array sorted: ", array) </span> <span>if __name__ == '__main__': </span> p <span>= Process(target=bubble_sort, args=([1,9,4,5,2,6,8,4],)) </span> p<span>.start() </span> p<span>.join() </span>
> target = bubble_sort,这意味着我们的新过程将运行Bubble_sort函数
>我们为流程类创建了一个实例,我们只需要启动该过程即可。这是通过编写p.start()来完成的。在这一点上,该过程已开始。
在此示例中,我们仅创建了一个子进程。您可能猜到,我们可以通过在过程类中创建更多实例来创建更多的子过程。
>池类允许您创建一个工作过程池,在下面的示例中,我们将研究如何使用它。这是我们的新示例:
<span>from multiprocessing import Process </span> <span>def bubble_sort(array): </span> check <span>= True </span> <span>while check == True: </span> check <span>= False </span> <span>for i in range(0, len(array)-1): </span> <span>if array[i] > array[i+1]: </span> check <span>= True </span> temp <span>= array[i] </span> array<span>[i] = array[i+1] </span> array<span>[i+1] = temp </span> <span>print("Array sorted: ", array) </span> <span>if __name__ == '__main__': </span> p <span>= Process(target=bubble_sort, args=([1,9,4,5,2,6,8,4],)) </span> p<span>.start() </span> p<span>.join() </span>>在此代码段中,我们有一个立方体(x)函数,该函数仅采用整数并返回其平方根。容易,对吗?
然后,我们创建一个池类的实例,而无需指定任何属性。池类类别默认每个CPU核心创建一个进程。接下来,我们使用一些参数运行地图方法。
地图方法将立方体函数应用于我们提供的峰值的每个元素 - 在这种情况下,这是从10到N的每个数字的列表。
的巨大优势是,列表上的计算是并行完成的!>
>充分利用Python多处理创建多个过程和进行并行计算不一定比串行计算更有效。对于低CPU密集型任务,串行计算比并行计算快。因此,重要的是要了解何时应该使用多处理 - 这取决于您执行的任务。
此片段基于上一个示例。我们正在解决相同的问题,该问题正在计算n个数字的平方根,但有两种方式。第一个涉及Python多处理的使用,而第二个则没有使用。我们正在使用时间库中的perf_counter()方法来衡量时间性能。
在我的笔记本电脑上,我得到了这个结果:如您所见,有一个以上的差异。因此,在这种情况下,多处理更好。
<span>from multiprocessing import Pool </span><span>import time </span><span>import math </span> N <span>= 5000000 </span> <span>def cube(x): </span> <span>return math.sqrt(x) </span> <span>if __name__ == "__main__": </span> <span>with Pool() as pool: </span> result <span>= pool.map(cube, range(10,N)) </span> <span>print("Program finished!") </span>
>让我们在代码中更改某些内容,例如N的值。让我们将其降低到n = 10000,看看会发生什么。
>这就是我现在得到的:
<span>from multiprocessing import Pool </span><span>import time </span><span>import math </span> N <span>= 5000000 </span> <span>def cube(x): </span> <span>return math.sqrt(x) </span> <span>if __name__ == "__main__": </span> <span># first way, using multiprocessing </span> start_time <span>= time.perf_counter() </span> <span>with Pool() as pool: </span> result <span>= pool.map(cube, range(10,N)) </span> finish_time <span>= time.perf_counter() </span> <span>print("Program finished in {} seconds - using multiprocessing".format(finish_time-start_time)) </span> <span>print("---") </span> <span># second way, serial computation </span> start_time <span>= time.perf_counter() </span> result <span>= [] </span> <span>for x in range(10,N): </span> result<span>.append(cube(x)) </span> finish_time <span>= time.perf_counter() </span> <span>print("Program finished in {} seconds".format(finish_time-start_time)) </span>
发生了什么事?现在,多处理现在是一个不好的选择。为什么?
与解决的任务相比,通过在过程之间分配计算来引入的高架太多。您可以看到时间表现有多大的区别。>
结论在本文中,我们通过使用Python多处理来讨论了Python代码的性能优化。
首先,我们简要介绍了哪些并行计算是使用它的主要模型。然后,我们开始谈论多处理及其优势。最后,我们看到平行化计算并不总是最佳选择,并且应将多处理模块用于并行化CPU结合任务。与往常一样,考虑到您要面临的具体问题并评估不同解决方案的利弊是一个问题。
我希望您发现学习有关Python的多处理与我一样有用。
关于Python多处理和并行编程>调试Python中的多处理程序可能会具有挑战性,因为传统调试工具可能在多处理环境中无法正常工作。但是,您可以使用几种技术来调试程序。一种方法是使用打印语句或记录来跟踪程序的执行。另一种方法是使用PDB模块的set_trace()函数在代码中设置断点。您还可以使用支持多处理的专业调试工具,例如多处理模块的log_to_stderr()函数,它允许您将进程的活动记录到标准错误。操作系统?
- 使用池类管理您的工作人员流程,因为它提供了一个更高级别的界面,该界面简化了创建和管理流程的过程。
- 始终通过调用流程类的join()方法来清理过程,该方法可确保该过程在程序继续之前完成。>
以上是Python多处理和并行编程指南的详细内容。更多信息请关注PHP中文网其他相关文章!