使用 Python 多处理并行加载大型数据集

时间:2021-07-17 15:53:41

标签: python-3.x multiprocessing python-multiprocessing

TLDR;

  1. 我想从磁盘并行读取多个文件
  2. 我的代码加载这些文件的速度非常快,但将它们合并到主进程的内存中速度很慢
  3. 我这样做正确吗?有没有更好的方法来跨进程共享内存?

背景: 我目前正在处理一个带有私人医院数据集(只有 3 GB!)的项目,并且希望能够更快地加载它(他们的磁盘很慢)。我在 36 个 CPU 的服务器上工作,所以我应该能够使用多个进程来加速它。但是,我无法看到改进。

设置: 我已将我的数据集拆分为 12 个二进制 PyTorch 文件 ('.pt'),我使用 torch.load(filename) 加载这些文件。这些文件每个都包含一个 dict E.G. 中的图像列表。第 0 个列表:{0:ListOfImages}。我想用不同的进程同时加载这些文件,然后按原始顺序将它们合并到一个列表中。我目前能够做到这一点,但似乎无法以比顺序加载更快的速度将数据合并到主进程中。

顺序基线加载:74 秒

我尝试了什么:

  • multiprocessing.Pool().map()(150 秒)
  • 多次迭代 process.start() + process.join()(300 秒 +)
  • 多线程:我以与顺序(74 秒)完全相同的时间加载数据集

到目前为止的多处理代码:

import multiprocessing as mp
import time
CORES = 12

def loadWorker(sharedDict,filename):
  t1 = time.time()
  temp = torch.load(filename)
  print("Dict Loaded in :{} seconds".format(time.time()-t1))
  t1=time.time()
  sharedDict.update(temp)
  print("Dict updated in :{} seconds".format(time.time()-t1))
  

filenames = ["namingconvention{}.pt".format(i) for i in range(CORES)]

jobs=[]
manager = mp.Manager()
sharedDict = manager.dict()
t1 = time.time()
for i,filename in enumerate(filenames):
  print("starting Process: {}".format(i))
  p = mp.Process(target=loadWorker, args=(sharedDict,filename))
  jobs.append(p)
  p.start()

for i,proc in enumerate(jobs):
  print("join Process {}".format(i))
  process.join()

print("dict created of length: {} in {} seconds".format(
  len(sharedDict),time.time()-t1)
)
  
images = []
for i in range(CORES):
  print("Appending Images: {}".format(i))
  images = images + list(images)

print("Images appended in {} seconds".format(time.time()-t1))

我做错了吗?有没有更好的方法在这些进程之间共享内存?

输出:

上面的输出: Image of the stdout

上面代码的输出带有CORES=1logger.setLevel(mp.SUBDEBUG) Image of debug stdout

0 个答案:

没有答案