平行計算作業補充(Python實現)
前情提要
之前由於平行計算的作業被視為類同或抄襲網路,正好最近學習Python,於是剛好在這裡作一個補充,新方法採用Python實現並行,一來學習用,二來為了完成作業。
Python平行計算
Python在平行計算方面使用的是GIL(Global Interperter Lock,全域性直譯器鎖),被認為的多執行緒其實是偽的,比較雞肋,但在實驗環境中,配合GPU,其實還不是很雞肋,在此我們就講解一下;
Python的原直譯器CPython是有GIL的,在執行程式碼過程中,會產生互斥鎖來限制執行緒對共享資源的訪問,而GIL的作用就是,一個進行同一時間只能允許一個執行緒運算,擺明的單執行緒啊!
由於CPython中的GIL的存在我們可以暫時不奢望能在CPython中使用多執行緒利用多核資源進行平行計算了,因此我們在Python中可以利用多程序的方式充分利用多核資源。
平行計算的目的是將所有的核心都執行起來以提高程式碼的執行速度,在python中由於存在全域性直譯器鎖(GIL)如果使用預設的python多執行緒進行平行計算可能會發現程式碼的執行速度並不會加快,甚至會比使用但核心要慢!!!
用到的庫
下面就來簡單介紹幾個Python平行計算中用到的庫,最後再使用Python實現一個小例子,應該可以完成作業了吧?
在Thread和Process中,應當優選Process,因為Process更穩定,而且,Process可以分佈到多臺機器上,而Thread最多隻能分佈到同一臺機器的多個CPU上。當然我們處理一個簡單的例子用哪個都可以。
這裡我們使用Python的multiprocessing模組,其中managers子模組還支援把多程序分佈到多臺機器上。一個服務程序可以作為排程者,將任務分佈到其他多個程序中,依靠網路通訊。由於managers模組封裝很好,不必瞭解網路通訊的細節,就可以很容易地編寫分散式多程序程式。
- 簡單介紹一下multiprocessing模組的用法:
multiprocessing模組提供了一個Process類來代表一個程序物件。建立子程序時,只需要傳入一個執行函式和函式的引數,建立一個Process例項,start()方法啟動,join()方法可以等待子程序結束後再繼續往下執行,通常用於程序間的同步。
程式碼舉例(程式碼經過實驗,在Python3上執行):
#-*-coding=utf-8-*- from multiprocessing import Process import os import time def run_process(name): time.sleep(2) print('Run child process %s is (%s). ' %(name, os.getpid())) pass def hello_world(): time.sleep(5) print('Run child process is (%s). ' %(os.getpid())) pass if __name__ == "__main__": print("Parent process is %s." % (os.getpid())) p1 = Process(target=run_process, args=('test', )) p2 = Process(target=hello_world) print(" process will start...... ") p1.start() p2.start() p1.join() print(" process end!")
輸出如下:
一些並行模組通過修改pyhton的GIL機制突破了這個限制,使得Python在多核電腦中也能夠有效的進行平行計算。PP(Parallel Python)模組就是其中一種。
- PP(Parallel Python)模組舉例:
安裝pp模組的時候出現了一個問題,在這裡做出解釋:
pip install pp==1.6.5
Collecting pp==1.6.5
Using cached https://files.pythonhosted.org/packages/14/e9/f69030681985226849becd36b04e2c0cb99babff23c8342bc4e30ded06b2/pp-1.6.5.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-1pnu5md4/pp/setup.py", line 12, in <module>
from pp import version as VERSION
File "/private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-1pnu5md4/pp/pp.py", line 121
print sout,
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(print sout, end=" ")?
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-xa12jeey/pp/
具體原因是因為pip工具預設呼叫了python3的語法運行了setup.py指令碼,但是該下載指令碼預設用的貌似是python2的語法,解決方法如下:
pip install setuptools --upgrade --user
接著執行:
pip install pp
出現:
Collecting pp
Using cached https://files.pythonhosted.org/packages/14/e9/f69030681985226849becd36b04e2c0cb99babff23c8342bc4e30ded06b2/pp-1.6.5.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-i2brisl3/pp/setup.py", line 12, in <module>
from pp import version as VERSION
File "/private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-i2brisl3/pp/pp.py", line 121
print sout,
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(print sout, end=" ")?
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/gk/4tnnvlmj0zzg74xzmnkq8g0c0000gn/T/pip-install-i2brisl3/pp/
上述原因是使用pip(python3版本)工具時呼叫了python2的指令碼,導致無法正常呼叫對應版本的setup.py指令碼;
使用pip2安裝出現:
Could not fetch URL https://pypi.python.org/simple/pp/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590) - skipping
Could not find a version that satisfies the requirement pp (from versions: )
No matching distribution found for pp
所以可能是python3上的pp模組並不是這個名字,我們使用其它方法把這個模組下載下來:
wget https://files.pythonhosted.org/packages/14/e9/f69030681985226849becd36b04e2c0cb99babff23c8342bc4e30ded06b2/pp-1.6.5.tar.gz
tar xvfz pp-1.6.5
cd pp-1.6.5
python setup.py install
這樣我們使用python2.7對pp模組進行了安裝,而且pp模組的最新版本1.6.5是隻支援python2的;接下來我們在python2.7下對pp模組進行引用,來完成平行計算的例子;
最後發現個問題,python版本對應有特定的pp版本,並不是不的支援了,詳細見網站PP模組版本,但是環境已經配好那就用python2吧暫時;
- 例子舉例,該例子實現了用平行計算的方法解決“從0到給定範圍內所有質數的和”:
#-*-coding=utf-8-*-
import time
import math
def isprime(n):
if not isinstance(n, int):
raise TypeError("argument passed to is_prime is not of 'int' type")
if n < 2:
return False
if n == 2:
return True
max = int(math.ceil(math.sqrt(n)))
i = 2
while i <= max:
if n % i == 0:
return False
i += 1
return True
def sum_primes(n):
return sum([x for x in range(2, n) if isprime(x)])
#序列程式碼
print("{beg} serial process {beg}".format(beg='-'*16))
startTime = time.time()
inputs = (100000, 100100, 100200, 100300, 100400, 100500, 100600, 100700)
results = [(input,sum_primes(input)) for input in inputs]
for input, result in results:
print("Sum of primes below %s is %s" % (input, result))
print("use: %.3fs"%( time.time()-startTime))
import pp
#並行程式碼
print("{beg} parallel process {beg}".format(beg='-'*16))
startTime = time.time()
job_server = pp.Server()
inputs = (100000, 100100, 100200, 100300, 100400, 100500, 100600, 100700)
jobs = [(input, job_server.submit(sum_primes, (input, ), (isprime, ),
("math", )) ) for input in inputs]
for input, job in jobs:
print("Sum of primes below %s is %s" % (input, job()))
print("use: %.3fs"%( time.time()-startTime ) )
執行得出結果:
實驗總結
這次作業補充讓我學習了兩個python平行計算的模組,一個是使用多執行緒方法的mutilprocessing,另一個是真正實現平行計算的pp模組,在今後的學習中,可以利用這些實現的平行計算去加速執行大規模的計算量,另外在深度學習方面我們有強大的numpy以及利用gpu的庫,總的來說在平行計算的方面我們還有很多東西可以實踐,今天就到這了,希望這個作業可以過。
相關推薦
平行計算作業補充(Python實現)
前情提要 之前由於平行計算的作業被視為類同或抄襲網路,正好最近學習Python,於是剛好在這裡作一個補充,新方法採用Python實現並行,一來學習用,二來為了完成作業。 Python平行計算 Python在平行計算方面使用的是GIL(Global Interp
用蒙特卡洛方法計算小遊戲獲勝概率(Python實現)
遊戲描述: 有兩人X和Y,遊戲之前兩人分別擁有籌碼x個和y個,兩人開始進行每人獲勝概率都是50%的比拼,如果X贏了,並且之前x>=y,那麼遊戲結束,X獲勝;如果X贏了,但是之前x<y,則X的籌碼翻倍,變成2x,Y的籌碼變成y-x,遊戲繼續; 問:當x,y取不同值
劍指offer-陣列中的逆序對計算(python實現)
劍指offer-陣列中的逆序對計算(牛客網題目,python實現) 問題描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸
算法:IP分割問題(python實現)
今天群裏有個朋友出了個題,是一家公司的面試題,題目如下(補充:對於ip0開頭的也是無效的,如分割後001.1.1.1這種是不可以的): 分析:這裏我們舉一個最簡單的例子1.1.1.12.2.2.2。首先能想到的解決方法肯定是使用循環了,我們可以寫2個循環嵌套(有點像冒泡排序)從第0個位置截取1個,從
遞歸——漢諾塔問題(python實現)
最大 大盤 其他 pytho 每次 直接 print int b- 規則 每次移動一個盤子 任何時候大盤子在下面,小盤子在上面 方法 假設共n個盤子 當n=1時: 直接把A上的一個盤子移動到C上(A->C) 當n=2時: 把小盤子從A放到B上(A->
堆排序(Python實現)
int 時間復雜度 pri 開始 堆排序 空間復雜度 繼續 末尾 小頂堆 堆排序(Heap Sort) 堆是一棵具有以下性質的完全二叉樹: 大頂堆:每個結點的值都大於或等於其左右孩子結點的值 小頂堆:每個結點的值都小於或等於其左右孩子結點的值 堆排序的主要思想: 將
求數組中兩兩相加等於20的組合(Python實現)
def n+1 odi lse java程序員 urn nlogn end 數組 題目 求數組中兩兩相加等於20的組合。 例:給定一個數組[1, 7, 17, 2, 6, 3, 14],這個數組中滿足條件的有兩對:17+3=20, 6+14=20。 解析 分為兩個步驟:
支援向量機(Python實現)
這篇文章是《機器學習實戰》(Machine Learning in Action)第六章 支援向量機演算法的Python實現程式碼。 1 參考連結 (1)支援向量機通俗導論(理解SVM的三層境界) (2)支援向量機—SMO論文詳解(序列最小最優化演算法) 2 實現程式
Logistic迴歸(Python實現)
這篇文章是《機器學習實戰》(Machine Learning in Action)第五章 Logistic迴歸演算法的Python實現程式碼。 1 參考連結 機器學習實戰 2 實現程式碼 from numpy import * def loadDataSet():
樸素貝葉斯(Python實現)
這篇文章是《機器學習實戰》(Machine Learning in Action)第四章 基於概率論的分類方法:樸素貝葉斯演算法的Python實現程式碼。 1 參考連結 機器學習實戰 2 實現程式碼 from numpy import * import feedpa
最短路徑問題(python實現)
解決最短路徑問題:(如下三種演算法) (1)迪傑斯特拉演算法(Dijkstra演算法)(2)弗洛伊德演算法(Floyd演算法)(3)SPFA演算法 第一種演算法: Dijkstra演算法 廣度優先搜尋解決賦權有向圖或者無向圖的單源最短路徑問題.是一種貪心的策略 演算法的思路 宣告一
分別用遞迴、迴圈、bisect實現二叉查詢(python實現)
1、遞迴實現二叉查詢 def binary_search_recursion(lst,target,low,high): if high < low: return None middle = (low + high)//2 if lst[middl
一分鐘學會讀csv檔案和寫csv檔案(python實現)
import csv with open('Python-Predict/Data/train.csv') as tra: rdr = csv.reader(tra) items = list(rdr) print("rdr:",rdr) print(items)
leetCode題目--反轉字串(python實現)
題目 編寫一個函式,其作用是將輸入的字串反轉過來。 示例 1: 輸入: "hello" 輸出: "olleh" 示例 2: 輸入: "A man, a plan, a canal: Panama" 輸出: "amanaP :lanac a ,
LeetCode題目--旋轉影象(python實現)
題目 給定一個 n × n 的二維矩陣表示一個影象。 將影象順時針旋轉 90 度。 說明: 你必須在原地旋轉影象,這意味著你需要直接修改輸入的二維矩陣。請不要使用另一個矩陣來旋轉影象。 示例 1: 給定 matrix =
LeetCode題目--驗證迴文字串(python實現)
題目 給定一個字串,驗證它是否是迴文串,只考慮字母和數字字元,可以忽略字母的大小寫。 說明:本題中,我們將空字串定義為有效的迴文串。 示例 1: 輸入: "A man, a plan, a canal: Panama" 輸出: true 示例 2:
LeetCode題目--有效的字母異位詞(python實現)
題目 給定兩個字串 s 和 t ,編寫一個函式來判斷 t 是否是 s 的一個字母異位詞。 示例 1: 輸入: s = "anagram", t = "nagaram" 輸出: true
LeetCode題目--字串中的第一個唯一字元(python實現)
題目 給定一個字串,找到它的第一個不重複的字元,並返回它的索引。如果不存在,則返回 -1。 案例: s = "leetcode" 返回 0. s = "loveleetcode", 返回 2. 注意事項:您可以假定該字串只包含小寫字母。 p
LeetCode題目--顛倒整數(python實現)
題目 給定一個 32 位有符號整數,將整數中的數字進行反轉。 示例 1: 輸入: 123 輸出: 321 示例 2: 輸入: -123 輸出: -321 示例 3: 輸入: 120 輸出: 21
LeetCode題目-- 最長公共字首(python實現)
題目 編寫一個函式來查詢字串陣列中的最長公共字首。 如果不存在公共字首,返回空字串 ""。 示例 1: 輸入: ["flower","flow","flight"] 輸出: "fl" 示例 2: 輸入: ["dog",