python - 如何使用 Python 实现最大写入速度?

标签 python performance file profiling

我正在编写一个可以进行高速数据采集的程序。采集卡可以以高达 6.8 GB/s 的速度运行(它在 PCIe3 x8 上)。现在我正在尝试流式传输到 RAM 磁盘,以查看我可以使用 Python 实现的最大写入速度。

该卡将给我 5-10 MB block ,然后我可以在某处写入。

我写了这段代码,它将一个 10MB 的 block 写入一个二进制文件 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 还很陌生。

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

最佳答案

我不知道你是否还在关注这个问题,但我发现你的问题很有趣,所以我在 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 感兴趣,我强烈建议您阅读本文。

关于python - 如何使用 Python 实现最大写入速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40665591/

相关文章:

python - 每个 start_url 抓取了多少项目

performance - Haskell 不会垃圾收集列表的头部吗?

ruby-on-rails - 返回 : Higher development speed than others?

python - 如何从 Python 中的任意换行符开始从文件中读取行

android - 在webView android中加载本地html文件

python - sys.stdout 在 bpython 中没有刷新属性

python - Flask sqlalchemy 中的 Sqlite 数据库备份和恢复

python - 在 Python 中获取 Killed 消息——内存是问题吗?

android - 如何布局嵌套的 RecyclerViews,同时保持高性能?

ios - NSDocumentDirectory 文件在 ios 中消失