我有一台服务器,RAID50配置为24个驱动器(两组12个),如果我运行:
dd if=/dev/zero of=ddfile2 bs=1M count=1953 oflag=direct
Run Code Online (Sandbox Code Playgroud)
我明白了:
2047868928 bytes (2.0 GB) copied, 0.805075 s, 2.5 GB/s
Run Code Online (Sandbox Code Playgroud)
但如果我跑:
dd if=/dev/zero of=ddfile2 bs=1M count=1953
Run Code Online (Sandbox Code Playgroud)
我明白了:
2047868928 bytes (2.0 GB) copied, 2.53489 s, 808 MB/s
Run Code Online (Sandbox Code Playgroud)
我知道O_DIRECT会导致页面缓存被绕过.但据我所知,它绕过页面缓存基本上意味着避免使用memcpy.使用带宽工具在我的桌面上进行测试我的最差情况是顺序内存写入带宽为14GB/s,我想在更新的更昂贵的服务器上,带宽必须更好.那么为什么额外的memcpy会导致> 2x减速?使用页面缓存时是否真的涉及更多内容?这不典型吗?
我正在编写一个可以进行高速数据采集的程序.采集卡可以以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)))
Run Code Online (Sandbox Code Playgroud)
我在RAM磁盘(R:\)上测试了这个,我得到了以下输出:
所以我想,我在RAM上获得了大约2.5 GB/s的速度.这还不错,但仍远离最大RAM吞吐量,但数字是一致的.因此,低吞吐量是一个问题.
第二个问题是,当我使用PCIe SSD测试此代码时(我使用1090 MB/s顺序写入的另一个软件进行基准测试),它给出了可比较的数字.
这让我觉得它是缓存和/或缓冲(?)所以我只是不测量实际的IO.我不确定究竟发生了什么,因为我对python很新.
所以我的主要问题是如何实现最大写入速度,而另一个问题是为什么我得到这些数字?
我正在与一位老师交谈,他告诉我读写系统调用正在使用缓冲区,因为系统规范中有一个变量控制您可以访问要读取/写入的设备的次数,并且当他等待在设备上写入时,系统使用缓冲区来存储数据。
我在另一篇 Stack Overflow 帖子(C fopen vs openfopen )上看到和函数的优点之一fwrite是这些函数使用缓冲区(这应该更快)。read我已经阅读了和sys call的手册页write,并且手册页没有讨论任何缓冲区。
我是不是误会了什么?read/ writeC 系统调用缓冲区如何工作?
file ×3
c ×2
io ×2
atomic ×1
dd ×1
go ×1
linux ×1
performance ×1
profiling ×1
python ×1
read-write ×1
system-calls ×1