2016-05-25 100 views
1

我想比較具有相同路徑結構和所有子文件夾中相同文件的兩個文件夾。該文件夾相當大,大小約爲80GB,文件數量爲8000.Python多重處理imap塊大小

我想確保兩個頂級目錄下的每個對應文件對具有相同的md5校驗和值。我編寫了一個簡單的樹型DFS函數,用於搜索兩個目錄下的所有文件,根據文件大小對它們進行排序,並將它們存儲在兩個列表中。

當我遍歷列表時,我發現執行所有比較非常耗時,並且CPU使用率也很低。

我認爲多處理模塊對於這種情況是很好的。這是我多執行:

from multiprocessing import Pool, cpu_count 
import hashlib 

def calc_md5(item): 
    m = hashlib.md5() 
    with open(item, 'rb') as f: 
     for chunk in iter(lambda: f.read(4096), b""): 
      m.update(chunk) 
    return m.hexdigest() 

def worker(args): 
    a, b = args 
    return calc_md5(a) == calc_md5(b) 

def multi_compare(queue_a, queue_b, thread): 
    pool = Pool(processes = cpu_count() - 1) 
    # Task iterable 
    task = zip(queue_a, queue_b) 
    # Multiprocessing 
    for retval in pool.imap_unordered(worker, task, chunksize = 5): 
     if not retval: 
      print "Bad Detected" 

這裏queue_a和queue_b是根據文件大小排序的要比較的文件的路徑。我期待更高的CPU使用率和更好的性能,但這種多處理方法似乎並非如此。雖然簡單的順序迭代大約需要3200秒才能完成,但多處理方法大約需要4600秒。

我很好奇爲什麼會出現這種情況?這是使用多處理的好處嗎?我的代碼中這種糟糕性能的瓶頸是什麼?有沒有辦法改進它?

編輯: 我已根據我的直覺設置了塊大小。我想我可以將它改爲queue_a或queue_b的長度,除以線程號,並將任務隊列排序爲它的前1/4,其中包含queue_a [0 :: thread]或queue_b [0 :: thread]元素,反之亦然。這會將相似大小的任務提供給所有線程,並始終保持所有線程都處於忙碌狀態。我不知道這是否是獲得額外性能的好方法,我仍在測試這方面的情況。

編輯: 上面的編輯測試需要4000秒才能完成。稍好於chunksize = 5。仍然比串行方法差。 所以我想問一下如何確定這個多處理程序的瓶頸。

謝謝!

+0

您的文件是否在HDD上?由於搜索速度緩慢,大多數硬盤驅動器在多線程讀取時都很糟糕。 – robyschek

+0

@robyschek是的,我認爲我在一臺HDD電腦上。我會用SSD測試它,看看。謝謝! – yc2986

回答

0

這是限制性能的IO。 對於CPU來說,MD5算法現在太簡單了。 以下代碼以GB/s爲單位計算MD5性能。

import time 
import hashlib 
from multiprocessing import Pool 

def worker(x): 
    data = bytearray(xrange(256)) * 4 * 1024 
    md5 = hashlib.md5() 
    for x in xrange(1024): 
     md5.update(data) 

if __name__ == '__main__': 
    num_workers = 4 
    pool = Pool(num_workers) 
    start = time.time() 
    pool.map(worker, xrange(num_workers)) 
    print num_workers/(time.time() - start), 'Gb/s' 

相對弱的intel的現代移動i3的CPU(2個核,4個線程) 能夠以每秒1千兆的速率來散列。將其與 SATA3 bandwidth比較,即600 Mb/s。 所以,即使使用SSD,磁盤接口也會限制散列速度。
在HDD上,情況更糟。 多個閱讀器將強制磁盤移動其讀取頭,導致比僅使用一個讀取器線程更多的延遲。 這就像閱讀一個高度碎片化的文件。
當數據集不是那麼大的操作系統的文件緩存可以幫助很大。不過,這不是你的情況。