Python 将IO重循环并行化:愚蠢的想法?

Python 将IO重循环并行化:愚蠢的想法?,python,parallel-processing,Python,Parallel Processing,对于某个目录中的每个文件,我需要读取其内容,并根据其内容对该文件进行处理 我想我应该将其并行化,以便可以同时处理多个文件。(我使用了python joblib。) 但它比顺序实现慢 这是因为文件上的每个操作都涉及IO,并且IO无法并行化吗?所以并行化并没有加速,并且由于在所有分叉进程之间切换而出现了减速 更多详情: 227732个文件(都是.dat和这里有几件事需要注意: joblib带来了很大的开销,因为它必须使用Python的多处理模块生成单独的进程,然后与这些进程通信以交换数据。它实际

对于某个目录中的每个文件,我需要读取其内容,并根据其内容对该文件进行处理

我想我应该将其并行化,以便可以同时处理多个文件。(我使用了python joblib。)

但它比顺序实现慢

这是因为文件上的每个操作都涉及IO,并且IO无法并行化吗?所以并行化并没有加速,并且由于在所有分叉进程之间切换而出现了减速


更多详情:


227732个文件(都是.dat和这里有几件事需要注意:

  • joblib带来了很大的开销,因为它必须使用Python的
    多处理
    模块生成单独的进程,然后与这些进程通信以交换数据。它实际上是用于科学计算工作负载的,这些开销被子进程中的繁重计算所抵消
  • 所有工作进程都在访问同一个磁盘。在任何时候,只有其中一个进程可以从磁盘上提取数据,因此,如果其余进程没有足够的计算要做,它们就会坐在那里等待。(与CPU带宽相比,磁盘带宽微不足道。)
  • 由于磁盘速度非常慢,在这种情况下,您通常需要两个工作进程,而不是“CPU/内核的数量”,因为超过第二个工作进程的每一个工作进程都只会增加开销。两个工作进程可以同时让CPU和一个内核保持忙碌(尽管它们甚至不会给您两倍的加速)
  • joblib 0.8有一个线程后端,您可以尝试

有多少个文件?你启动了多少个工作人员?你是如何在工作人员之间分发文件的?顺序实施需要多长时间,并行实施需要多长时间?人们不能像你的建议那样笼统地陈述,也不能不知道更多的细节。抱歉,我希望有一个强有力的答案o因此,有类似问题的用户可以提出一个更一般、抽象的问题。我将添加所有细节。对于Python中IO密集型并行性,最好运行单个进程,并通过
线程化
模块实现并行性。但是,对于您的问题,没有简单的答案。有些变量其他评论中提到了ABLE,但它也取决于文件的大小、使用的文件系统的类型等。好的,谢谢。我想这需要练习。有没有关于如何找出准确答案的建议?(例如冗长的教程?)较新的joblib实际上可以使用线程;pass
backend=“threading”
并行
构造函数。
from joblib import Parallel, delayed

def parallel(data_dir,dirlist):
  Parallel(n_jobs=-1)(delayed(good_or_bad_train_case)(filename, data_dir) 
                      for filename in dirlist if filename.endswith('.dat'))

def sequential(data_dir,dirlist):
  t = time.clock()
  [good_or_bad_train_case(filename,data_dir) for filename in 
   dirlist if filename.endswith('.dat')]

def good_or_bad_file(filename,data_dir):
  fullname = os.path.join(data_dir, filename)
  rootname = os.path.splitext(filename)[0]
  f = open(fullname)
  content = f.readlines()
  if 'NoPhotoOfJoint\r\n' in content or 'PoorPhoto\r\n' in content:
    os.symlink(fullname,data_dir+'/bad_data/'+rootname+'.jpg')
    os.symlink(fullname,data_dir+'/bad_data/'+rootname+'.dat')
  else: 
    os.symlink(fullname,data_dir+'/good_data/'+rootname+'.jpg')
    os.symlink(fullname,data_dir+'/good_data/'+rootname+'.dat')