Why does Python not use 100% of the processor?

3

I'm developing a Python application where in some snippets, it requires a lot of CPU for calculations.

However, I realize that even at these "bottleneck" points, the CPU never reaches more than 50% use.

Of course the program slows down, while it has "spare" CPU that could make it faster.

For example, the process below takes (in my PC), 15 seconds :

from math import *
import time
ini = time.time()

for x in range(10**8):
    a = cos(x)

print ("Tempo Total: ", time.time() - ini)

But during processing, only a few logical processors are used, with only 1 processor experiencing more demand, but still less than 100%:

How to make Python use 100% CPU in critical processes?

    
asked by anonymous 06.10.2018 / 18:57

1 answer

1

In your case what is happening is the following, you are running your routine on a single thread on a system (CPU) that has 4 logical cores.

You will need to rewrite your algorithm to be multi-thread , or check if you can run different instances on specific cores. I do not know any other way.

Come on ..

I set up an example with a plots calculation to show the difference in performance between each scenario.

  

Scenario 1 - Execute SEM Thread

import time
ini = time.time()

def tabuada( threadName, numero):
    count = 0
    while count < 300000000:
        count +=1
        #print(" %s x %s = %s\n" % (numero, count, count*numero))
tabuada("Thread-1",2)
tabuada("Thread-1",3)
tabuada("Thread-1",4)


print ("Tempo Total: ", time.time() - ini)

In this execution I had a result:

Total Time: 35.65071749687195

  

Scenario 2 - Running Parallel Thread COM

import time
import _thread
ini = time.time()

def tabuada( threadName, numero):
    count = 0
    while count < 100000000:
        count +=1
        #print(" %s x %s = %s\n" % (numero, count, count*numero))
    print ("Tempo Total: ", time.time() - ini)    

def tabuada2( threadName, numero):
    count = 0
    while count < 100000000:
        count +=1
        #print(" %s x %s = %s\n" % (numero, count, count*numero))
    print ("Tempo Total: ", time.time() - ini)      


def tabuada3( threadName, numero):
    count = 0
    while count < 100000000:
        count +=1
        #print(" %s x %s = %s\n" % (numero, count, count*numero))
    print ("Tempo Total: ", time.time() - ini)          

try:
    _thread.start_new_thread( tabuada, ("Thread12",2,) )
    _thread.start_new_thread( tabuada2, ("Thread14",3,) )
    _thread.start_new_thread( tabuada2, ("Thread15",4,) )
except:
    print('Erro')

In this execution I had a result:

Total Time: 10.11058759689331

Total Time: 11.129863500595093

Total Time: 11.548049688339233

The total time in this case was 11.54s, since this was the time that took the most time for a thread. And the total time displayed on each line represents how much each thread took in its execution.

As we can see, time falls a lot when we divide the task, but why? Because when we create different threads the OS interprets as different processes and it allocates in different locations and cores inside my CPU.

As I said at the beginning, if you want to use your CPU more and optimize processing time, I advise you to use threads

Here are two cool links to the content:

Multi-thread programming in python

Python Threads

    
09.10.2018 / 18:23