[英]Optimising for O_DIRECT writes
我正在尝试编写一个需要非常快速地写入磁盘的应用程序。 我已经达到了写入磁盘的性能目标,这很棒。
但是,我注意到这么快地写入磁盘会占用大量CPU时间:一个内核已用完,另一个内核已用完80%,另外两个内核已用完10-20%。 因此,我听说O_DIRECT可以通过避免将所有这些副本复制到内核空间然后复制到磁盘来减少CPU消耗。
我运行了一个小型测试程序,确认了这一点-CPU使用率下降到一个内核的50%-更好。
但是,我的吞吐率从来没有达到正常写入时的吞吐率,而且要使其变得更快,我不得不使用非常大的记录大小(大约130MB!)。
所以,问题是,我猜:
我的环境是Linux,我使用RAID 50,并且能够缓冲写入,直到达到最佳记录大小为止。 一次只有一名作家。
引用此页面 :
使用O_DIRECT时,内核将直接从作为[a]参数传递给读/写syscall的用户空间缓冲区指向[指向]物理内存,直接进行DMA。 因此,在用户空间内存和内核缓存之间的副本中不会花费CPU和内存带宽,并且在缓存管理中(例如,缓存查找,每页锁等),也不会在内核中花费CPU时间。
基本上,使用O_DIRECT
时,您需要为CPU性能而使用吞吐量。 内核停止为您优化吞吐量,作为回报,您将获得可预测的结果和完全的控制权。
长话短说:使用O_DIRECT
您将不得不进行缓存和其他优化操作,从而增加吞吐量。 巨大的唱片大小现在似乎并不奇怪。
我不知道其他任何方法,但是我不是Linux专家。 随便问一下:)
您将需要以某种方式安排同时保持更多的I / O并以最佳大小提交它们。 当内核将您的写I / O一起缓冲时,可能会产生许多好处:
所以
有比O_DIRECT更好的降低CPU使用率的方法吗?
是的,发送更大的I / O到磁盘首选的最佳大小。
如何获得与内核相似的吞吐量?
理想情况下,执行上述操作(发送最佳大小的I / O),并确保磁盘喜欢的最大I / O一次处于运行状态(例如,如果要使用阻塞例程,则通过异步提交或通过多个线程/进程提交) ),然后按磁盘的LBA顺序提交I / O。 稍微不太理想的技巧是向下发送大量I / O,并迫使内核将其拆分以创建并行性,但这并不是最佳选择。
您是否尝试过使用mmap
和msync
? 我不知道它是更快还是更少的CPU占用,但是由于它代表了另一种I / O方法(基本上是由内核为您执行I / O),所以它可能是一个有趣的场所。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.