在 HD 中进行数据密集型读写的最佳实践是啥?

Posted

技术标签:

【中文标题】在 HD 中进行数据密集型读写的最佳实践是啥?【英文标题】:Which are the best practices for data intensive reading and writing in a HD?在 HD 中进行数据密集型读写的最佳实践是什么? 【发布时间】:2011-06-15 06:15:10 【问题描述】:

我正在开发一个 C++ 应用程序(在 Linux 机器中运行),它在读取日志文件和将派生结果写入磁盘方面非常密集。我想知道优化这类应用程序的最佳做法是:

哪些操作系统调整可提高性能? 哪些编程模式可以提高 IO 吞吐量? 预处理数据(转换为二进制、压缩数据等)是否有用? 分块/缓冲数据是否有助于提高性能? 我应该注意哪些硬件功能? 哪些做法最适合分析和衡量这些应用程序的性能? (在这里表达我所缺少的担忧)

是否有一本很好的读物可以让我了解这方面的基础知识,以便我可以根据我的问题调整现有的专业知识?

谢谢

【问题讨论】:

将数据保存在缓冲区中,尽量少写,太慢了。 【参考方案1】:

压缩肯定有很大帮助,而且比调整操作系统要简单得多。查看Boost.iostreams 库中的gzipbzip2 支持。不过,这会对处理器造成影响。

time 命令开始测量这些类型的作业。如果系统时间与用户时间相比非常高,那么您的程序会花费大量时间进行系统调用。如果挂钟(“真实”)时间比系统时间和用户时间高,则它正在等待磁盘或网络。 top 命令显示程序的 CPU 使用率明显低于 100%,这也是 I/O 瓶颈的标志。

【讨论】:

我们通过使用 zcat bigfile.gz | ourprogramourprorogram < bigfile 获得大约 3 倍的加速。以 zcat 进行解压缩的 CPU 使用率较高、我们的程序不阻塞 IO 以及大(10Gb)文件的初始 gzip 压缩为代价。 bzip2 给我们的性能比 zcat 低——可能是因为解压花费了更多时间——但这一切都取决于你花费多少 CPU 时间与解压。【参考方案2】:

1) 检查磁盘的扇区大小。 2) 确保磁盘已进行碎片整理。 3) 读取“本地”数据到您为提高缓存局部性所做的最后一次读取(缓存由操作系统执行,许多硬盘驱动器也具有内置缓存)。 4) 连续写入数据。

为了提高写入性能,将数据块缓存在内存中,直到达到扇区大小的倍数,然后启动异步写入磁盘。在确定数据已被写入(即同步写入)之前,不要覆盖当前正在写入的数据。双重或三重缓冲在这里会有所帮助。

为了获得最佳读取性能,您可以双缓冲读取。因此,假设您在读取时缓存了 16K 块。将第一个 16K 从磁盘读取到块 1。启动将第二个 16K 异步读取到块 2。开始处理块 1。当您完成块 1 时,同步块 2 的读取并开始异步读取到块 1将第 3 个 16K 块放入第 1 块。现在处理第 2 块。完成同步读取第 3 个 16K 块后,启动第 4 个 16K 块的异步读取到第 2 块并处理第 1 块。冲洗并重复,直到处理完所有数据。

如前所述,您必须读取的数据越少,从磁盘读取所花费的时间就越少,因此可能值得读取压缩数据并花费 CPU 时间扩展读取的每个块。在写入之前同样压缩块将节省您的磁盘时间。这是否真的成功将取决于您处理数据的 CPU 密集程度。

此外,如果对块的处理是不对称的(即处理块 1 的时间可能是处理块 2 的 3 倍),则考虑对读取进行三倍或更多缓冲。

【讨论】:

【参考方案3】:

获取有关您将要写入/读取的卷的信息,并创建与卷特征匹配的缓冲区。例如10 * 集群大小。

缓冲有很大帮助,因为它可以最大限度地减少你必须做的写入量。

【讨论】:

【参考方案4】:

正如这里所说,您应该检查块的大小。您可以使用 stat 系列函数来执行此操作。 在 struct stat 中,此信息位于字段 st_blksize。

第二件事是函数 posix_fadvise(),它为操作系统提供有关分页的建议。您告诉系统您将如何使用文件(甚至是文件的片段)。您可以在手册页上找到更多信息。

【讨论】:

【参考方案5】:

在 Windows 上,使用带有 FILE_FLAG_SEQUENTIAL_SCAN 和/或 FILE_FLAG_NO_BUFFERING 的 CreateFile() 而不是 fopen() - 至少是为了立即写入此返回而不是等待数据刷新到磁盘

【讨论】:

以上是关于在 HD 中进行数据密集型读写的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 silex 中获取用户数据的最佳实践是啥?

在 Web 服务中处理 id 的最佳实践是啥?

在 R 中处理时间序列的最佳实践是啥?

对 XML 模式进行版本控制的最佳实践是啥?

从客户端浏览器读取/写入 HSQL 的最佳实践是啥?

在 React 组件和服务之间进行通信的最佳实践是啥?