Reputation: 15
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
Upvotes: 1
Views: 470
Reputation: 13403
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 (e.g. cache).
Try to replace your workload with one that is very suited for multiprocessing (e.g. 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
Upvotes: 2