2016-11-17 51 views
5

我正在寫一個程序,將做高速數據採集。採集卡可以運行在6.8 GB/s(在PCIe3 x8上)。現在,我正在嘗試流入RAM磁盤以查看我可以用Python實現的最大寫入速度。如何用Python實現最大的寫入速度?

該卡將給我5-10 MB塊,然後我可以在某處寫入。

我寫了這段代碼,它將一個10MB的塊寫入一個二進制文件500次。我在Windows 7 64位上使用Anaconda2,並使用了Anaconda加速器中的剖析器。

block = 'A'*10*1024*1024 
filename = "R:\\test" 
f = os.open(filename, os.O_CREAT| os.O_BINARY|os.O_TRUNC|os.O_WRONLY|os.O_SEQUENTIAL) 

p = profiler.Profile(signatures=False) 
p.enable() 
start = time.clock() 
for x in range(500): 
    os.write(f,block) 
transferTime_sec = time.clock() - start 
p.disable() 
p.print_stats() 

print('\nwrote %f MB' % (os.stat(filename).st_size/(1024*1024))) 

我測試了這一個RAM磁盤(R:\)上我得到了以下的輸出:

enter image description here

所以我想,我得到的東西約2.5 GB/s的內存。這並不差,但仍然遠遠超過最大內存吞吐量,但數字是一致的。所以低吞吐量是一個問題。

第二個問題是,當我用PCIe SSD(我用另一個軟件以1090 MB/s連續寫入爲基準)測試此代碼時,它給出了可比較的數字。

enter image description here

這讓我覺得,它的緩存和/或緩衝(?)等我只是沒有測量​​實際IO。我不確定發生了什麼事情,因爲我對python相當陌生。

所以我的主要問題是如何實現最大寫入速度,而側面的問題是爲什麼我得到這些數字?

+0

我在想,爲什麼你用'os.open()'而不是'open()'? –

+0

男性肯定沒有進程攔截寫入,是的,我看着你的Windows後衛。 –

+0

@ShadyAtef對文件屬性的更多控制,可能是直接IO –

回答

0

我不知道你是否還在尋找這個問題,但我發現你的問題很有趣,所以我在Linux筆記本上試了一下。

我在python 3.5上運行了你的代碼,發現你還需要有os.O_SYNC標誌以避免緩衝問題(基本上os.write函數在所有數據寫入磁盤之前都不會返回)。我也用time.time()代替time.clock(),這給了我更好的結果。

import os 
import time 
import cProfile 

def ioTest(): 
    block = bytes('A'*10*1024*1024, 'utf-8') 
    filename = 'test.bin' 
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | 
       os.O_SYNC) 
    start = time.time() 
    for x in range(500): 
     os.write(f,block) 
    os.close(f) 
    transferTime_sec = time.time() - start 
    msg = 'Wrote {:0f}MB in {:0.03f}s' 
    print(msg.format(os.stat(filename).st_size/1024/1024, 
        transferTime_sec)) 
cProfile.run('ioTest()') 

此外,這post說說使用os.O_DIRECT標誌,將使用DMA和避免瓶頸。我只好用MMAP模塊,使之在我的機器上工作:

import os 
import time 
import cProfile 
import mmap 

def ioTest(): 
    m = mmap.mmap(-1, 10*1024*1024) 
    block = bytes('A'*10*1024*1024, 'utf-8') 
    m.write(block) filename = 'test.bin' 
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | 
       os.O_SYNC, os.O_DIRECT) 
    start = time.time() 
    for x in range(500): 
     os.write(f,m) 
    os.close(f) 
    transferTime_sec = time.time() - start 
    msg = 'Wrote {:0f}MB in {:0.03f}s.' 
    print(msg.format(os.stat(filename).st_size/1024/1024, 
        transferTime_sec)) 
cProfile.run('ioTest()') 

這降低了40%的時間寫我的機器上......也不錯。 我沒有使用我的機器上沒有的os.O_SEQUENTIAL和​​。

[編輯]:我發現如何使用這個site的os.O_DIRECT標誌,它很好地深入地解釋了它。如果你對Python的性能和IO有興趣,我強烈建議閱讀本文。