简体   繁体   中英

Python - Why would multiprocessing code be slower than single threaded?

I'm using Python's multiprocessing library and I was following this repo's code . As you can see based on main.py and terminal something odd is going on. Based on the documentation and a tutorial I read. The time library should print before the workers finish, because I did not call the <process object>.join() function and time is on the main process, but as we can see in terminal it prints Found 8 GPUs for rendering. Using device 0. Found 8 GPUs for rendering. Using device 0. which comes from do_some_task function. Something else weird that is going on is using multiprocessing is much slower than just iteratively calling do_some_task function. As we can see in terminal . What is going on?

main.py

from worker import Worker
from task import do_some_task
import time

tic = time.time()
num_workers = 8

workers = [Worker() for i in range(num_workers)]

for worker in workers:
    worker.child.send(("task", None))

for i, worker in enumerate(workers):
    obs_workers[i] = worker.child.recv()

for worker in workers:
    worker.child.send(("close", None))

toc = time.time()

print(f'Multi time was: {toc-tic}')

tic = time.time()

for i in range(num_workers):
    do_some_task()

toc = time.time()
print(f'Single time: {toc-tic}')

worker.py

import multiprocessing
from task import do_some_task

def worker_process(remote: multiprocessing.connection.Connection, cfg: dict, seed: int):
    while True:
        cmd, data = remote.recv()
        if cmd == "task":
            do_some_task()
        elif cmd == "close":
            remote.close()
            break
        else:
            raise NotImplementedError

class Worker:
    def __init__(self, cfg, seed) -> None:
        self.child, parent = multiprocessing.Pipe()
        self.process = multiprocessing.Process(target=worker_process, args=(parent, cfg, seed))
        self.process.start()

terminal

Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Found 8 GPUs for rendering. Using device 0.
Multi time was: 40.21380949020386
Found 8 GPUs for rendering. Using device 0.
Single time: 5.607028484344482

You are not doing multiprocessing here. You just add task in a queue. => They will be executed by a core. Please use this library

For instance, this code snippet source1 allows you to use every cores you have, just edit the worker function with the code that you wants to multiprocess

import os
import time
import multiprocessing
import numpy as np

def worker(n):
    factorial = np.math.factorial(900000)
    # rank = multiprocessing.current_process().name one can also use
    rank = multiprocessing.current_process()._identity[0]
    print(f'I am processor {rank}, got n={n}, and finished calculating the factorial.')


cpu_count = multiprocessing.cpu_count()
input_params_list = range(1, cpu_count+1)


pool = multiprocessing.Pool(cpu_count)
pool.map(worker, input_params_list)
pool.close()
pool.join()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM