0

In this video, he shows how multithreading runs on physical(Intel or AMD) processor cores.

https://youtu.be/ecKWiaHCEKs

and

is python capable of running on multiple cores?

All these links basically say:
Python threads cannot take advantage of many physical cores. This is due to an internal implementation detail called the GIL (global interpreter lock) and if we want to utilize multiple physical cores of the CPU we must use true parallel multiprocessing module

But when I ran this below code on my laptop

import threading
import math

def worker(argument):
    for i in range(200000):
        print(math.sqrt(i))
    return

for i in range(3):
    t = threading.Thread(target=worker, args=[i])
    t.start()

I got this result

enter image description here

Questions:

1. Why did code run on all of my physical CPU cores instead of using one out of four physical cores of my CPU? If so what is the point of multiprocessing module?

2. The second time, I changed the above code to create only one thread and that also took all of the CPU physical cores and took 4/4 physical cores to run.Why is that?

Noogrammer
  • 37
  • 5

2 Answers2

2

https://docs.python.org/3/library/math.html

The math module consists mostly of thin wrappers around the platform C math library functions.

While python itself can only execute a single instruction at a time, a low level c function that is called by python does not have this limitation.
So it's not python that is using multiple cores but your system's well optimized math library that is wrapped by python's math module.

That basically answers both your questions.

Regarding the usefulness of multiprocessing: It is still useful for those cases, where you're trying to parallelize pure python code or code that does not call libraries that already use multiple cores. However, it comes with inter process communication (IPC) overhead that may or may not be larger than the performance gain that you get from using multiple cores. Tuning IPC is therefore often crucial for multiprocessing in python.

swenzel
  • 6,745
  • 3
  • 23
  • 37
  • Well explained, but now I am wondering how in this video 'https://youtu.be/ecKWiaHCEKs' it only took one CPU core by running the same math.sqrt( ) function. – Noogrammer Jun 15 '21 at 08:16
  • @Noogrammer I answered this comment's question in my answer to your problem. My answer adds to this answer, and I hope it helps you understand. – akaButters Jun 15 '21 at 08:19
  • @Noogrammer their system's math library probably had a different implementation of the `sqrt` function that doesn't use multiple cores. Not every system has the same core libraries. They have a compatible interface but not necessarily the same implementation. – swenzel Jun 15 '21 at 08:31
1

First to answer one misconception / error from your code:

import threading
import math

def worker(argument):
    for i in range(200000):
        print(math.sqrt(i))
    return

for i in range(3):
    t = threading.Thread(target=worker, args=[i])
    t.start()

You are NOT using multiprocessing you are using threading. They are similar BUT NOT THE SAME. Threading IS AFFECTED by GIL, Multiprocessing IS NOT.

So when you ran 4 threads, a CPU intensive worker/job like sqrt() WILL NOT have the benefit of the thread because it is CPU-bound, and CPU-bound tasks ARE hindered by the GIL (wehn used in a Thread() vs. Process()

To have all four cores work well without the GIL, change your code to:

import multiprocessing
import math

def worker(argument):
    for i in range(200000):
        print(math.sqrt(i))
    return

for i in range(3):
    t = multiprocessing.Process(target=worker, args=[i])
    t.start()
akaButters
  • 375
  • 1
  • 12
  • I knew it before but my question is not that, I wanted to know how multithreading runs true parallel when it is not supposed to do so. I knew before multi-processing runs true parallel and multithreading was supposed to run on a single core. – Noogrammer Jun 15 '21 at 08:21
  • But yeah, @swenzel is totally right, I just wanted to give you the full scoop in case you used something that isn't a thin wrapper. (Like the ```hashlib.sha3_256()``` for instance, which I use across multi-cores to process data faster) – akaButters Jun 15 '21 at 08:28