2016-11-17 99 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有兴趣,我强烈建议阅读本文。