【问题标题】:Parallel Disk I/O并行磁盘 I/O
【发布时间】:2014-05-20 01:45:59
【问题描述】:

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

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

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

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

但有趣的是,我注意到小文件 (= 445MB) 才会出现预期的减速。

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

Q1:那么文件读取机制到底是什么?

Q2:优化从传统硬盘读取文件的最佳方法是什么?

技术规格:

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

【问题讨论】:

  • s/python/操作系统/
  • 您的操作系统可能在块级别实现了至少 64K 字节的预读策略。
  • 并且在引擎盖下有缓冲的 IO。注意:引擎盖下的内容不是特定于 python 的。一个好的起点是检查 C 和操作系统中发生的情况。
  • 您所描述的是与虚拟分页系统有关的问题,以及如何在缓冲 IO 中为操作系统从文件中读取数据。欲了解更多信息,en.wikipedia.org/wiki/Virtual_memory
  • 从您列出的 python 代码中,“for line infile”可能会产生大量开销,具体取决于它们如何实现迭代器。您是否尝试过实施不同的方法来读取文件? (我讨厌 5 分钟编辑规则……不小心按了 Enter)

标签: python macos python-3.3 disk-io


【解决方案1】:

观察到的行为是以下原因的结果:

  1. 缓冲IO
  2. 一种调度算法,用于决定读取 HDD 必要扇区的顺序

缓冲IO

根据操作系统和读取块的大小,整个文件有可能适合一个块,即在单个读取命令中读取的内容。这就是为什么较小的文件更容易读取的原因

调度算法

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

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

如果在读取头可以提供来自同一文件的下一块行之前完成对一块行执行的计算,则连续读取同一文件之间的时间很重要,该过程只是等待直到另一块行变得可用.这是减速的原因之一

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

由于这两个问题的综合影响,并行处理许多大文件会比串行处理要慢。当然,在处理blockSize 多行之前处理完numProcesses * blockSize 多行可以从HDD 中读取时更是如此

【讨论】:

    【解决方案2】:

    另一个想法是分析您的代码

    try:
        import cProfile as profile
    except ImportError:
        import profile
    
    profile.run("process()")
    

    【讨论】:

    • 更喜欢使用此替代解决方案编辑您的其他答案
    【解决方案3】:

    这里是一个使用内存映射文件的例子

    import mmap 
    with open("hello.txt", "r+b") as f:
         mapf = mmap.mmap(f.fileno(), 0)
         print(mapf.readline()) 
         mapf.close()
        enter code here
    

    【讨论】:

    • 内存映射文件在这里有什么帮助?在最初的帖子中,Python 主要是逐行读取文件,从不使用太多内存(除非行很大,因为文件是在文本模式下打开的,所以不应该是这种情况)。
    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 2019-11-12
    • 2012-08-10
    相关资源
    最近更新 更多