我正在编写一个程序来进行高速数据采集。该采集卡的运行速度可达6.8GB/s(在PCIe3 x8上)。现在,我正在尝试流到RAM磁盘,以查看我可以用Python实现的最大写入速度。
卡将给我5-10 MB的块,然后我可以写在某处。
我编写了这段代码,它将10 to块写入一个二进制文件500次。我在Windows764位上使用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:)上进行了测试,得到了以下输出:

所以我想,我在RAM上得到了大约2.5GB/s的数据。这并不坏,但仍远未达到最大RAM吞吐量,但数字是一致的。因此,低吞吐量是一个问题。
第二个问题是,当我用PCIe SSD测试这段代码时(我用另一个1090 MB/s的连续写入软件进行了基准测试),它给出了类似的数字。

这让我觉得它在缓存和/或缓冲(?)所以我只是不测量实际的IO。我不知道到底发生了什么,因为我对python相当陌生。
所以我的主要问题是如何达到最大的写入速度,一个次要的问题是,为什么我得到这些数字?
发布于 2017-05-25 17:40:13
我不知道你是否还在处理这个问题,但我发现你的问题很有趣,所以我在Linux笔记本电脑上试了一下。
我在python3.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()')此外,本帖子还讨论了使用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和os.O_BINARY。
编辑:我发现了如何使用这个站点中的os.O_DIRECT标志,这很好地解释了它。如果您对性能感兴趣,并且在Python中直接使用IO,我强烈建议您阅读这篇文章。
https://stackoverflow.com/questions/40665591
复制相似问题