- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
下面的程序从一个文件中读入一堆行并解析它们。它可能会更快。另一方面,如果我有多个内核和多个文件要处理,那应该没什么大不了的;我可以并行运行作业。
不幸的是,这在我的 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/
我有这个代码: private void doSomething() throws InterruptedException { WorkerThread w= new WorkerThrea
我有一个关于并发的简单问题。我正在通过可运行接口(interface)实现线程和并发。如果我首先初始化线程,然后在初始化后单独调用 start,或者如果我初始化线程并从同一个 for 循环中调用 st
我刚开始接触并发,所以如果我问一些明显/愚蠢的问题,请多多包涵。我正在尝试采取第一步来改造我必须利用 Java 货币的模型。没有详细说明,我有一部分模型加载了一些文件,然后在给定请求时它返回文件上的一
我有一个 java 类,它同时被很多线程访问,我想确保它是线程安全的。该类有一个私有(private)字段,它是字符串到字符串列表的映射。我已将 Map 实现为 ConcurrentHashMap 以
正如我们所知,ThreadPoolExecutor 使用一些 BlockingQueue 作为传入任务的队列。我想要的是让 ThreadPoolExecutor 有一个 second 队列,用于准备就
若两个操作同时发生,则称为并发,但事实上,操作是否在时间上重叠并不重要。由于分布式系统复杂的时钟同步问题,现实中很难严格判断两个事件是否同时发生。 为更好定义并发性,并不依赖确切发生时间,即若两个操作
这是计算任意数的阶乘的代码: unsigned long long factorial(int n) { Concurrency::combinable products=Concurrency:
我找不到使用最新的 JAVA 并发例程的这种特定情况的示例。 我计划使用threads 来处理来自开放队列的项目,该队列可能包含 0 到数千个请求。我想限制在任何给定时间有不少于 0 且不超过 10
我正在迈出学习多线程的第一步,并构建一个小测试程序,以便为自己提供一些见解。由于重新排序的可能性,我不相信我的解决方案是安全的.. 这是主程序: public class SynchTest {
我目前正在从事一个搜索引擎项目。为了更快的爬行速度,我在每次链接访问时使用一个 goroutine。但是我遇到了两个让我疑惑的问题! 第一个是代码示例: package main import "fm
我一直在使用 Azure 存储队列通过 QueueTrigger 属性来提供 WebJob。我将 QueueTrigger 配置为将多个项目出队以进行并发处理,如下所示: public static
我正在使用Rails的一些中间件,使用的是最新版本: pfernand-2-mn:~ pfernand$ rails -v Rails 3.1.2 这是rake middleware的输出: use
我一直在尝试使用 Azure Data Lake Store,并且在文档中 Microsoft 声称该系统针对低延迟小文件写入进行了优化。测试它我尝试对单个文件执行大量并行任务写入,但此方法在大多数情
假设我有一个同步的 HashMap,它有一个字符串作为键和一个列表作为值。 Map> map = Collections.synchronizedMap(new HashMap>()); 这个列表是线
这个问题在这里已经有了答案: ConcurrentModificationException for ArrayList [duplicate] (6 个答案) 关闭 9 年前。 我有一个关于我的
问题 当且仅当有空闲 CPU 时,我如何扩展以使用更多线程?像 ThreadPoolExecutor 这样的东西,它在 cpu 核心空闲时使用更多线程,如果没有空闲则更少或只使用一个线程。 用例 现状
这个问题已经有答案了: 已关闭13 年前。 Possible Duplicate: Thread safety in Java class 我正在阅读实践中的 Java 并发,并且我遇到了一个令我困惑
Stroustrup 在C++ 第 4 版第 1193 页中给出了以下示例。我的问题是使用两个线程的并发程序,一个用于 f(),另一个用于 g() 以及 Stroustrup 的声明: if a li
我是一名优秀的程序员,十分优秀!