C++ 优化O_直接写入

C++ 优化O_直接写入,c++,c,linux,io,C++,C,Linux,Io,我正在尝试编写一个应用程序,它需要非常快地写入磁盘。我已经达到了写入磁盘的性能目标,这非常好 然而,我注意到,如此快速地写入磁盘占用了大量的CPU时间:一个内核已达到最大值,另一个为80%,另外两个为10-20%。所以我听说O_DIRECT可以通过避免所有这些拷贝进入内核空间然后拷贝到磁盘来减少CPU消耗 我运行了一个小测试程序,证实了这一点——CPU使用率下降到一个内核的50%——好得多 然而,我从来没有获得过与正常写入时相同的吞吐量,为了加快速度,我必须使用非常大的记录大小(大约130MB!

我正在尝试编写一个应用程序,它需要非常快地写入磁盘。我已经达到了写入磁盘的性能目标,这非常好

然而,我注意到,如此快速地写入磁盘占用了大量的CPU时间:一个内核已达到最大值,另一个为80%,另外两个为10-20%。所以我听说O_DIRECT可以通过避免所有这些拷贝进入内核空间然后拷贝到磁盘来减少CPU消耗

我运行了一个小测试程序,证实了这一点——CPU使用率下降到一个内核的50%——好得多

然而,我从来没有获得过与正常写入时相同的吞吐量,为了加快速度,我必须使用非常大的记录大小(大约130MB!)

所以,我想问题是:

  • 有没有比O_DIRECT更好的方法来降低CPU使用率? 或
  • 如何获得与内核类似的吞吐量
我的环境是Linux,我使用的是RAID 50,我能够缓冲写操作,直到达到最佳记录大小。一次只有一位作者。

引用:

使用O_DIRECT,内核将直接从/到作为[a]参数传递给读/写系统调用的用户空间缓冲区指向的物理内存进行DMA。因此,在用户空间内存和内核缓存之间的副本中不会花费CPU和内存带宽,在管理缓存时也不会在内核中花费CPU时间(如缓存查找、每页锁定等)

基本上,当使用
O_DIRECT
时,您是在用吞吐量换取CPU性能。内核停止为您优化吞吐量,作为回报,您可以获得可预测的结果和完全控制

长话短说:使用
O_DIRECT
您必须自己进行缓存和其他优化,以提高吞吐量。巨大的记录大小现在看起来不那么奇怪了


我不知道还有其他方法,但我不是linux大师。请随意询问:)

您是否试用过
mmap
msync
?我不知道它是更快还是更少的CPU密集型,但由于它代表了一种全新的I/O方法(基本上是内核为您执行I/O),因此它可能是一个有趣的场所。

您需要以某种方式安排更多I/O同时运行,并以最佳大小提交它们。当内核将您的写I/O缓冲在一起时,有许多好处:

  • 可以将连续的I/O合并成更大的I/O。如果是这样,就有机会节省开销,因为内核现在可以向下提交1 64Kbyte I/O,而不是向下提交8个小的4kbyte I/O(例如)
  • 它打开了一个平行提交的可能性。如果内核能够批量处理256k,那么它现在就可以同时发送8个I/O,从而获得更高的Idepth
所以

有没有比O_DIRECT更好的方法来降低CPU使用率

是,将较大的I/O发送到磁盘首选的最佳大小

如何获得与内核类似的吞吐量


理想情况下,执行上述操作(发送最佳大小的I/O),并确保磁盘喜欢的最大I/O立即保持运行(例如,通过异步提交或通过多线程/进程提交,如果要使用阻塞例程),并按磁盘的LBA顺序提交I/O。一个稍微不太理想的技巧是发送巨大的I/O,并强制内核拆分它们以创建并行性,但这不太理想。

我刚刚尝试了mmap和msync—我似乎得到了与O_DIRECT类似的故事—当我加速到一个非常大的记录大小时,效率会更好,但在其他方面,性能会很差。谢谢你的建议,谢谢你。我想我问的是,内核做了哪些优化?因为据推测,我可以复制它以获得与内核类似的吞吐量——或者采用更好的方法。看看磁盘I/O统计数据,它看起来不像是内核缓冲区在写入之前达到了100MBs我不是linux专家,我只有16岁:)我猜应该是缓存和缓冲(可能是使用动态缓冲区,每次写入后其大小会翻倍)。我建议您只看一下linux内核源代码,但我不知道您应该从哪里开始看。对不起,在这种情况下我帮不了什么忙:)