How to find out the number of CPUs using python
If you're interested into the number of processors available to your current process, you have to check cpuset first. Otherwise (or if cpuset is not in use), multiprocessing.cpu_count()
is the way to go in Python 2.6 and newer. The following method falls back to a couple of alternative methods in older versions of Python:
import os
import re
import subprocess
def available_cpu_count():
""" Number of available virtual or physical CPUs on this system, i.e.
user/real as output by time(1) when called with an optimally scaling
userspace-only program"""
# cpuset
# cpuset may restrict the number of *available* processors
try:
m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$',
open('/proc/self/status').read())
if m:
res = bin(int(m.group(1).replace(',', ''), 16)).count('1')
if res > 0:
return res
except IOError:
pass
# Python 2.6+
try:
import multiprocessing
return multiprocessing.cpu_count()
except (ImportError, NotImplementedError):
pass
# https://github.com/giampaolo/psutil
try:
import psutil
return psutil.cpu_count() # psutil.NUM_CPUS on old versions
except (ImportError, AttributeError):
pass
# POSIX
try:
res = int(os.sysconf('SC_NPROCESSORS_ONLN'))
if res > 0:
return res
except (AttributeError, ValueError):
pass
# Windows
try:
res = int(os.environ['NUMBER_OF_PROCESSORS'])
if res > 0:
return res
except (KeyError, ValueError):
pass
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
# BSD
try:
sysctl = subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
stdout=subprocess.PIPE)
scStdout = sysctl.communicate()[0]
res = int(scStdout)
if res > 0:
return res
except (OSError, ValueError):
pass
# Linux
try:
res = open('/proc/cpuinfo').read().count('processor\t:')
if res > 0:
return res
except IOError:
pass
# Solaris
try:
pseudoDevices = os.listdir('/devices/pseudo/')
res = 0
for pd in pseudoDevices:
if re.match(r'^cpuid@[0-9]+$', pd):
res += 1
if res > 0:
return res
except OSError:
pass
# Other UNIXes (heuristic)
try:
try:
dmesg = open('/var/run/dmesg.boot').read()
except IOError:
dmesgProcess = subprocess.Popen(['dmesg'], stdout=subprocess.PIPE)
dmesg = dmesgProcess.communicate()[0]
res = 0
while '\ncpu' + str(res) + ':' in dmesg:
res += 1
if res > 0:
return res
except OSError:
pass
raise Exception('Can not determine number of CPUs on this system')
Portable way of detecting number of *usable* CPUs in Python
I don't think you will get any truly portable answers, so I will give a correct one.
The correct* answer for Linux is len(os.sched_getaffinity(pid))
, where pid
may be 0
for the current process. This function is exposed in Python 3.3 and later; if you need it in earlier, you'll have to do some fancy cffi
coding.
Edit: you might try to see if you can use a function int omp_get_num_procs();
if it exists, it is the only meaningful answer I found on this question but I haven't tried it from Python.
How to determine the maximum number of processes that can be run per CPU core using python?
The number of processes a CPU core can run simultaneously is equal to the number of threads per CPU core. And to get the number of threads per CPU core in python you can do something like this:
import psutil
total_threads = psutil.cpu_count()/psutil.cpu_count(logical=False)
print('You can run {} processes per CPU core simultaneously'.format(total_threads))
To check different processors your script can run on you can use:
print(psutil.Process().cpu_affinity())
Multiprocessing in python vs number of cores
First you are mixing up threads and processes: in Python only threads not processes have to share a lock on their interpreter.
If your are using the multiprocessing library then, your are using Python processes which have their own interpreter.
When you are using Python processes, their execution is managed by your operating system scheduler, in the same manner as every other processes in your computer.
If you have more processes than CPU cores then the extra processes are waiting in background to be scheduled.
This usually happen when an other process terminates, wait on an IO, or periodically with clock interrupts.
How to get the number of threads per cores in python
You can use psutil
module in python3.
python3 -m pip install psutil
The psutil.cpu_count
method returns the number of logical CPUs in the system (same as os.cpu_count in Python 3.4) or None if undetermined. logical cores means the number of physical cores multiplied by the number of threads that can run on each core (this is known as Hyper Threading). If logical is False return the number of physical cores only (Hyper Thread CPUs are excluded) or None if undetermined.
import psutil
threads_count = psutil.cpu_count() / psutil.cpu_count(logical=False)
Get number of busy CPUs in Python
There are a number of complications...
- you can't determine which CPUs are busy
Processes (and threads) are scheduled by the Linux kernel on any CPU. Even determining the "current CPU" is awkward -- see How can I see which CPU core a thread is running in?
multiprocessing.Pool
is designed to start up N workers, which run "forever." Each accepts a task from a queue, does some work, then outputs data. APool
doesn't change size.
Two suggestions:
- the uptime command outputs something like this:
19:05:07 up 4 days, 20:43, 3 users, load average:
0.99, 1.01, 0.82
The last three numbers are the "load average" over the last minute, five minutes, and 15 minutes. Consider using the first number to load-balance your application.
- consider having your application do
time.sleep(factor)
after completing each piece of work.
Thus you can increase the factor when the system is busy (high load average), and make the delay shorter when the system is more idle (low load; ie surfing). Pool stays same size.
Is there a pytorch method to check the number of cpus?
just use this :
os.cpu_count()
How many processors should be used with multiprocessing.Pool?
The difference between the two is clearly stated in the doc:
multiprocessing.cpu_count()
Return the number of CPUs in the system.This number is not equivalent to the number of CPUs the current process can use. The number of usable CPUs can be obtained with
len(os.sched_getaffinity(0))
.
So even if you are on a 128-core system, your program could have been somehow limited to only run on a specific set of 10 out of the 128 available CPUs. Since affinity also applies to child threads and processes, it doesn't make much sense to spawn more than 10. You could however try to increase the number of available CPUs through os.sched_setaffinity()
before starting your pool.
import os
import multiprocessing as mp
cpu_count = mp.cpu_count()
if len(os.sched_getaffinity(0)) < cpu_count:
try:
os.sched_setaffinity(0, range(cpu_count))
except OSError:
print('Could not set affinity')
n = max(len(os.sched_getaffinity(0)), 96)
print('Using', n, 'processes for the pool')
pool = mp.Pool(n)
# ...
See also man 2 sched_setaffinity
.
Related Topics
How to Dynamically Compose an or Query Filter in Django
Is the Server Bundled with Flask Safe to Use in Production
Prime Number Check Acts Strange
Remove File After Flask Serves It
How to Install Pycrypto on Windows
Matplotlib Xticks Not Lining Up with Histogram
Execute a File with Arguments in Python Shell
How to Load a Module from Code in a String
Django Db Settings 'Improperly Configured' Error
Virtualenv --No-Site-Packages and Pip Still Finding Global Packages
Pandas "Can Only Compare Identically-Labeled Dataframe Objects" Error
How to Properly Assert That an Exception Gets Raised in Pytest