如何用Python实现最高写入速度?

时间:2016-11-17 21:44:12

标签: python performance file profiling

我正在编写一个可以进行高速数据采集的程序。采集卡可以以6.8 GB / s的速度运行(它在PCIe3 x8上)。现在我正在尝试流式传输到RAM磁盘,以查看我可以使用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

所以我想,我在RAM上获得了大约2.5 GB / s的速度。这还不错,但仍远离最大RAM吞吐量,但数字是一致的。因此,低吞吐量是一个问题。

第二个问题是,当我使用PCIe SSD测试此代码时(我使用1090 MB / s顺序写入的其他软件进行基准测试),它提供了可比数字。

enter image description here

这让我觉得它是缓存和/或缓冲(?)所以我只是不测量实际的IO。我不确定究竟发生了什么,因为我对python很新。

所以我的主要问题是如何实现最大写入速度,而另一个问题是为什么我会得到这些数字?

1 个答案:

答案 0 :(得分:0)

我不知道你是否还在照顾这个问题,但我发现你的问题很有趣,所以我在Linux笔记本电脑上试了一下。

我在python 3.5上运行你的代码并发现你需要有os.O_SYNC标志以避免缓冲问题(基本上os.write函数在所有数据都没有返回之前返回写在磁盘上)。我还将time.clock()替换为time.time(),这会给我更好的结果。

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_SEQUENTIALos.O_BINARY

[编辑] :我找到了如何使用此site中的os.O_DIRECT标志,该标志非常详尽地解释了它。如果您对Python中的性能和直接IO感兴趣,我强烈建议您阅读本文。