Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no influence after using more than 2 processes in Pool?

By using the map function in the multiprocessing library I see no difference in execution time when using more than 2 processes. I'm running the program using 4 cores.

The actual code is pretty straight forward and calculates the first 4000 fibonacci numbers 4 times (= the amount of cores). It distributes the work evenly between N cores (e.g. when using a Pool with 2 processes, each process will calculate the first 4000 fibonacci numbers twice). This whole process is done for N = 1 up to the amount of cores.

The output, with in every row the amount of cores and the corresponding execution time in seconds, is:

  1. 3,147
  2. 1,72
  3. 1,896
  4. 1.899

Does anyone know why there is no decrease in execution time given more than 2 cores? The actual code is:

import multiprocessing
from time import time


def F(_):
    for n in range(4 * 10 ** 3):
        a, b = 0, 1
        for i in range(0, n):
            a, b = b, a + b
    return


def pool_fib():
    n_cores = multiprocessing.cpu_count()
    args = list(range(multiprocessing.cpu_count()))
    for i in range(1, n_cores + 1):
        with multiprocessing.Pool(i) as p:
            start = time()
            p.map(F, args)
            print(i, time() - start)


if __name__ == '__main__':
    pool_fib()
like image 413
GroovyP Avatar asked Sep 02 '25 11:09

GroovyP


1 Answers

Provided you are using a fairly modern CPU, multiprocessing.cpu_count() won't give you the number of physical cores your machine has, but the number of hyper-threads. In a nutshell, hyper-threading allows a single physical core to have n (most commonly, two) pipelines, which fools your OS into thinking you've got n times the number of cores you really have. This is helpful, when you are doing some stuff that might starve a core with data (most notably, IO or RAM lookups caused by cache-misses), but your workload is purely arithmetic and it is not likely to starve your CPU, resulting in little to no gains from hyper-threading. And the little gains you might get will be overshadowed by multiprocessing overhead, which is quite significant.

P.S.

I usually post this sort of things as comments, but I've exceeded the comment size limitation. By the way, if you've chosen the Fibonacci series for something more that just an example, you might want to consider a faster algorithm: Fast Fibonacci computation

like image 176
Eli Korvigo Avatar answered Sep 03 '25 23:09

Eli Korvigo