【问题标题】:Using multiprocessing to process many files in parallel使用多处理并行处理多个文件
【发布时间】:2017-11-30 05:56:42
【问题描述】:

我想了解我使用multiprocessing.Pool 的方式是否有效。我想并行执行的方法是一个脚本,它读取某个文件,进行计算,然后将结果保存到不同的文件中。我的代码如下所示:

from multiprocessing import Pool, TimeoutError
import deepdish.io as dd

def savefile(a,b,t,c,g,e,d):
    print a
    dd.save(str(a),{'b':b,'t':t,'c':c,'g':g,'e':e,'d':d})


def run_many_calcs():
    num_processors = 6
    print "Num processors - ",num_processors
    pool = Pool(processes=num_processors)     # start 4 worker processes
    for a in ['a','b','c','d','e','f','g','t','y','e','r','w']:
        pool.apply(savefile,args=(a,4,5,6,7,8,1))

我怎样才能看到一个进程在其中一个处理器中完成后立即继续到下一个文件?

【问题讨论】:

  • 您有理由怀疑是这种情况吗?我们需要了解dd.save() 内部发生的一些事情,以评估这是否是一个好的设计。如果它受 I/O 限制(尤其是所有进程相互独立读取同一个文件时),您只会造成拥塞。
  • 我不认为从多个进程同时读取同一个文件会是一个大问题——操作系统应该很容易处理它——但是它们都写入相同的“不同”输出文件?后者可能是一个重要的瓶颈。
  • @martineau 每个进程都将数据保存到具有相同结构的不同输出文件中。后来我对文件进行后处理以在熊猫中构建一个数据框,但我认为保存每个文件会更好,所以如果程序由于某种原因崩溃我仍然需要完成一些工作..
  • 这听起来是个好策略。您希望如何“看到”另一个进程在完成时开始?换句话说,为什么你在savefile() 中已经拥有的print a 不够好?反正你为什么要看这个。我怀疑这里可能存在 X:Y 问题...

标签: python multithreading multiprocessing python-multiprocessing


【解决方案1】:

在考虑任何程序的性能时,您必须确定性能是否受 I/O(内存、磁盘、网络等)或计算(核心数量、核心速度等)的限制。

如果 I/O 是瓶颈,那么拥有多个进程、更快的 CPU 等都是没有意义的。

如果计算一直在占用,那么值得在多个进程等方面进行投资。“计算时间”通常被诊断为问题所在,但仔细调查后发现受到计算机内存总线的限制速度,而不是内核的时钟频率。在这种情况下,添加多个进程会使事情变得更糟......

检查

您可以通过对代码进行一些性能分析来检查自己的情况(肯定会有大量用于 Python 的分析工具)。

我的猜测

现在大部分时间都是 I/O 成为瓶颈。如果您不想分析您的代码,押注更快的 SSD 可能是最好的初始方法。

无法解决的计算机科学问题

现代 CPU 的架构特性(L1、L2、L3 缓存、QPI、超线程)都是计算机设计中潜在问题的征兆;内核对于我们可以环绕它们的 I/O 来说太快了。

例如,与内核速度相比,将 1 个字节从 SDRAM 传输到内核所需的时间非常慢。人们只需要希望 L3、L2 和 L1 高速缓存子系统已经正确预测了对 1 个字节的需求,并且已经提前获取了它。如果没有,就会有很大的延迟;这就是超线程可以帮助提高计算机其他进程的整体性能的地方(它们可以介入并完成一些工作),但对于停滞的程序绝对没有任何作用。

从文件或网络中获取的数据确实非常慢。

文件系统缓存

在您的情况下,听起来您有 1 个单一输入文件;这至少会被操作系统缓存在 RAM 中(只要它不是太大)。

您可能很想自己将其读入内存;我不会打扰。如果它很大,您将分配大量内存来保存它,如果这对于机器中的 RAM 来说太大了,那么操作系统无论如何都会将一些 RAM 交换到虚拟内存页面文件中,而您的情况会更糟比以前。如果它足够小,那么操作系统很有可能会为您缓存整个内容,从而为您省去麻烦。

在一定程度上,写入的文件也会被缓存。最终,如果“总处理时间”意味着所有数据都写入磁盘,那么您将无能为力;无论您在内存中做了什么以及操作系统缓存了什么,您都必须等待磁盘完成写入。

操作系统的文件系统缓存可能会给人一种文件写入已完成的初步印象(操作系统很快会继续整合实际驱动器上的数据),但一旦写入缓存已满,同一程序的连续运行将被阻止.

如果您确实分析了您的代码,请确保长时间(或重复)运行它,以确保分析器所做的测量揭示了计算机的真实基础性能。如果结果显示大部分时间都在 file.Read() 或者 file.Write()...

【讨论】:

    猜你喜欢
    • 2021-09-18
    • 1970-01-01
    • 2012-07-19
    • 2021-01-13
    • 1970-01-01
    • 2015-05-03
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多