gpt4 book ai didi

c++ - 如何在 Linux 中提高 SSD I/O 吞吐量并发性

转载 作者:IT王子 更新时间:2023-10-29 01:25:43 25 4
gpt4 key购买 nike

下面的程序从一个文件中读入一堆行并解析它们。它可能会更快。另一方面,如果我有多个内核和多个文件要处理,那应该没什么大不了的;我可以并行运行作业。

不幸的是,这在我的 arch 机器上似乎不起作用。运行该程序的两个拷贝只比运行一个拷贝(见下文)快一点点(如果有的话),而且还不到我的驱动器能力的 20%。在具有相同硬件的 ubuntu 机器上,情况要好一些。我获得了 3-4 核的线性扩展,但我的 SSD 驱动器容量仍达到 50% 左右。

随着内核数量的增加,哪些障碍会阻碍 I/O 吞吐量的线性扩展?可以采取哪些措施来提高软件/操作系统方面的 I/O 并发性?

附言- 对于下面提到的硬件,单核速度足够快,如果我将解析移动到单独的线程,读取将受 I/O 限制。还有other optimizations用于提高单核性能。然而,对于这个问题,我想关注并发性以及我的编码和操作系统选择如何影响它。

详细信息:

这里有几行iostat -x 1输出:

使用 dd 将文件复制到/dev/null:

Device:         rrqm/s   wrqm/s     r/s     w/s     rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda 0.00 0.00 883.00 0.00 113024.00 0.00 256.00 1.80 2.04 2.04 0.00 1.13 100.00

运行我的程序:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda 1.00 1.00 141.00 2.00 18176.00 12.00 254.38 0.17 1.08 0.71 27.00 0.96 13.70

同时运行我的程序的两个实例,读取不同的文件:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda 11.00 0.00 139.00 0.00 19200.00 0.00 276.26 1.16 8.16 8.16 0.00 6.96 96.70

还好一点!添加更多内核不会增加吞吐量,实际上它开始降级并变得不那么一致。

这是我的程序的一个实例和 dd 的一个实例:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda 9.00 0.00 468.00 0.00 61056.00 0.00 260.92 2.07 4.37 4.37 0.00 2.14 100.00

这是我的代码:

#include <string>

#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>

typedef boost::filesystem::path path;
typedef boost::filesystem::ifstream ifstream;

int main(int argc, char ** argv) {
path p{std::string(argv[1])};
ifstream f(p);
std::string line;
std::vector<boost::iterator_range<std::string::iterator>> fields;

for (getline(f,line); !f.eof(); getline(f,line)) {
boost::split (fields, line, boost::is_any_of (","));
}
f.close();
return 0;
}

这是我编译它的方式:

g++ -std=c++14 -lboost_filesystem -o gah.o -c gah.cxx
g++ -std=c++14 -lboost_filesystem -lboost_system -lboost_iostreams -o gah gah.o

编辑:更多细节

clear memory cache (free page cache, dentries and inodes)在运行上述基准测试之前,要防止 linux 从缓存中提取页面。

我的进程似乎受 CPU 限制;切换到 mmap 或通过 pubsetbuf 更改缓冲区大小对记录的吞吐量没有明显影响。

另一方面,缩放是 IO 绑定(bind)的。如果我在运行我的程序之前将所有文件放入内存缓存中,吞吐量(现在通过执行时间来衡量,因为 iostat 看不到它)与内核数量成线性比例。

我真正想了解的是,当我使用多个顺序读取进程从磁盘读取数据时,为什么吞吐量不随进程数线性增长,直到接近驱动器的最大读取速度?为什么我会在不使吞吐量饱和的情况下达到 I/O 限制,当我这样做时如何取决于我在其上运行的操作系统/软件堆栈?

最佳答案

你不是在比较相似的东西。

你在比较

Copying a file to /dev/dull with dd:

(我假设你的意思是 /dev/null...)

int main(int argc, char ** argv) {
path p{std::string(argv[1])};
ifstream f(p);
std::string line;
std::vector<boost::iterator_range<std::string::iterator>> fields;

for (getline(f,line); !f.eof(); getline(f,line)) {
boost::split (fields, line, boost::is_any_of (","));
}
f.close();
return 0;
}

第一个只是读取原始字节而不关心它们是什么并将它们转储到位桶中。您的代码按行读取,需要识别,然后将它们拆分为 vector 。

您读取数据的方式是读取一行,然后花时间处理它。您比较代码的 dd 命令从不花时间做读取数据以外的事情 - 它不必读取然后处理然后读取然后处理...

关于c++ - 如何在 Linux 中提高 SSD I/O 吞吐量并发性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43722841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com