好吧,讓我們走吧!
>
鑰匙要點>平行和串行計算
想像您有一個巨大的問題要解決,您一個人。您需要計算八個不同數字的平方根。你做什麼工作?好吧,您沒有很多選擇。您從第一個數字開始,然後計算結果。然後,您繼續與其他人一起。
>如果您有三個擅長幫助您的數學擅長的朋友怎麼辦?他們每個人都會計算兩個數字的平方根,並且您的工作將更容易,因為工作負載平均分佈在您的朋友之間。這意味著您的問題將被更快地解決。
>好吧,這一切都很清楚嗎?在這些示例中,每個朋友代表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>
然後,我們創建一個池類的實例,而無需指定任何屬性。池類類別默認每個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中文網其他相關文章!