python - 并行磁盘 I/O

标签 python macos python-3.3 disk-io

我有几个想要阅读的日志文件。不失一般性,假设日志文件处理如下:

def process(infilepath):
    answer = 0
    with open (infilepath) as infile:
        for line in infile:
            if line.startswith(someStr):
                answer += 1
    return answer

由于我有很多日志文件,我想在这个问题上使用多处理(我的第一个错误:我应该使用多线程;请有人告诉我为什么)

在这样做时,我突然想到,任何形式的并行处理在这里实际上都是无用的,因为我受到硬盘上只有一个读头这一事实的限制,因此,只能读取一个文件。一次阅读。事实上,根据这种推理,由于来自不同文件的行可能被同时请求,读头可能需要不时地显着移动,导致多进程方法比串行方法慢。所以我决定回到单个进程来读取我的日志文件。

有趣的是,我注意到小文件 (<= 40KB) 确实获得了加速,并且只有大文件 (>= 445MB) 才注意到预期的速度下降。

这让我相信 python 可以分块读取文件,其大小超过我一次请求的一行。

问题1:那么底层的文件读取机制是什么?

问题2:优化从传统硬盘读取文件的最佳方式是什么?

技术规范:

  • python3.3
  • 5400rpm传统硬盘
  • Mac OSX 10.9.2(小牛队)

最佳答案

观察到的行为是由于:

  1. 缓冲IO
  2. 决定 HDD 必需扇区读取顺序的调度算法

缓冲IO

根据操作系统和读取 block 大小,整个文件可能会放入一个 block 中,这是在单个读取命令中读取的内容。这就是为什么较小的文件更容易读取

调度算法

较大的文件(文件大小>读取 block 大小),必须以 block 大小 block 读取。因此,当请求对多个文件中的每个文件进行读取时(由于多重处理),指针必须移动到 HDD 的不同扇区(对应于文件所在的位置)。这种重复的 Action 有两件事:

  1. 增加连续读取同一文件的时间间隔
  2. 放弃读取扇区预测器,因为一个文件可能跨越多个扇区

如果在读取头可以提供同一文件中的下一个行 block 之前对一个行 block 执行的计算完成,则同一文件的连续读取之间的时间很重要,该过程只需等待直到另一个行 block 变得可用。这是速度放缓的原因之一

放弃读取预测器是不好的,原因与 why throwing off the branch predictor is bad 几乎相同。 .

由于这两个问题的综合影响,并行处理许多大文件会比串行处理它们慢。当然,当处理 blockSize 许多行在 numProcesses * blockSize 许多行可以从 HDD 中读出

之前完成时,情况更是如此。

关于python - 并行磁盘 I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22918814/

相关文章:

python - Python 中的蒙特卡罗模拟 : How to get exactly identical transition probabilities from modeled data?

python - ./setup.py install 的 --install-base 参数到底是什么意思?

python - Django 1.8 在 Serializer 中获取 kwargs

swift - 初始加载后未触发 viewDidAppear

c++ - 在启用 C++ 的 OSX 10.9 上编译 GMP 库

python - finder 和 meta hook 有什么区别?

python - 如何在python shell中导入virtualenv中的包

python - ">"无法将 python 命令的输出定向到文件

syntax-error - pyglet.gl语法错误

python - str.maketrans 在交互式 python 中可用,但在 python 脚本中不可用?