简体   繁体   中英

Python multiprocessing code running slower than single threaded one

The Python Multiprocessing performance on my i7 7700HQ is significantly slower than non-parallel one.

While planning to parallelize my Select and Update code for my single table database in mssql, I tried to first parallelize a simple code. The program simply prints multiples of the argument. I tried single-threaded, multi-process with Process object and also with Pool object. Single threaded always performed best.

import time

def foobar(a):
    for i in range(1,10000):
        print(a*i)
    return
if __name__ == "__main__":
   Tthreading = time.clock()
    p1= Process(target= foobar, args=(3,))
    p2 = Process(target= foobar, args= (2,))
    p3 = Process(target= foobar, args= (4,))
    p4 = Process(target=foobar, args=(123,))

    allprocess.start

    allprocess.join

    print(time.clock() - Tthreading)

    #Single-threaded
    Tsingle = time.clock()
    foobar(3)
    foobar(2)
    foobar(4)
    foobar(123)
    print(time.clock() - Tsingle)


I expected the multi-process to be much faster since there are no shared resources(no functions, variables that need to be accessed between threads) and IPC.

Single Threaded time: 0.32s

Multi-Process time: 0.53s

Actually, there is one important shared resource in your example, your monitor (or stdout ).

print is a relatively slow operation (compared to CPU cycles...), and it causes contention between your proccesses.

Benchmarking parallel work correctly is a tough task, it is affected by the great many factors and features of a CPU (eg cache).

Try to replace your workload with one that is very suited for multiprocessing (eg working in a parallel on different parts of an array, matrix multiplication...)

One more important thing: spawning the new processes also takes time, and for it to pay off the work done in each process needs to be significant. If you increase your loop's range a little bit, the difference should be in favor of the Multi-process version:

import time
from multiprocessing import Process

def foobar(a):
    for i in range(1,10000000):
        a*i
    return

if __name__ == "__main__":
    Tthreading = time.time()
    p1= Process(target= foobar, args=(3,))
    p2 = Process(target= foobar, args= (2,))
    p3 = Process(target= foobar, args= (4,))
    p4 = Process(target=foobar, args=(123,))

    allprocess = [p1,p2,p3,p4]
    for p in allprocess:
        p.start()

    for p in allprocess:
        p.join()

    print(time.time() - Tthreading)

    #Single-threaded
    Tsingle = time.time()
    foobar(3)
    foobar(2)
    foobar(4)
    foobar(123)
    print(time.time() - Tsingle)

on my machine this outputs:

0.44509196281433105

1.3775699138641357

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