51

Using Python is there any way to find out the processor information... (I need the name)

I need the name of the processor that the interpreter is running on. I checked the sys module but it has no such function.

I can use an external library also if required.

user225312
  • 126,773
  • 69
  • 172
  • 181

10 Answers10

39

The platform.processor() function returns the processor name as a string.

>>> import platform
>>> platform.processor()
'Intel64 Family 6 Model 23 Stepping 6, GenuineIntel'
user225312
  • 126,773
  • 69
  • 172
  • 181
  • 2
    can anyone say whether this is platform independent output. ie. does it always give the exact same output for the same CPU on windows/linux/osx? – John La Rooy Jan 30 '11 at 11:22
  • @gnibbler: Is there any reason to doubt that the output may vary? Though I hope someone can confirm. – user225312 Jan 30 '11 at 11:31
  • 3
    @Spacedman: "An empty string is returned if the value cannot be determined." Have the same issue. – gorlum0 Jan 30 '11 at 12:02
  • I think the real question is what does the OP want the processor name for. CPU names were simple up until the first Pentiums, then AMD appeared, and everyone else started making similar CPUs, and now each speed of processor has a different name, and then you've got multiple CPUs and cores and so on... Unless the 'name' is burnt into the silicon then each OS is free to represent it in whatever string it wants. – Spacedman Jan 30 '11 at 12:14
  • 3
    Note that many platforms do not provide this information or simply return the same value as for machine(). NetBSD does this.: I have this problem. I need to know if I'm running on intel or amd, since my scripts are generating configuration settings for compiling software, and depending on intel/amd I wanna set the xHost or msse3 option. – Jens Timmerman Apr 10 '12 at 08:46
  • I thought that this was (essentially) only supported on Windows? – dbn Oct 25 '12 at 22:32
  • Depends what it's using to get the information. If it is using the lowest level information, then it is actually making an assembly language call of an [actual processor opcode: `cpuid`](http://en.wikipedia.org/wiki/CPUID). [Usage instructions here.](http://www.codeguru.com/cpp/w-p/system/hardwareinformation/article.php/c9087/Three-Ways-to-Retrieve-Processor-Information.htm#page-2) – Assad Ebrahim Apr 20 '13 at 21:18
  • @Spacedman: The "name" *is* burnt into the silicon, and any piece of x86 machine code can extract it by [running the CPUID instruction](http://www.sandpile.org/x86/cpuid.htm). e.g. `Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz`. That's where the family / stepping and Vendor string (`GenuineIntel`) also come from. – Peter Cordes Jul 24 '16 at 08:55
  • @PeterCordes @user225312 I found the answer by @David [here](https://stackoverflow.com/questions/19185632/how-to-get-the-processor-name-in-python) to be more in line with the information contained in `/proc/cpuinfo` for Linux systems – Addison Klinke Jun 12 '19 at 15:45
  • 2
    @JohnLaRooy I get only an 'x86_64' string running this on Ubuntu 18.04. – ares Jul 29 '19 at 19:26
  • i've tried this out on a mac, ibm and hp machine, and got 'i386' , 'ppc64le', and 'x86_64' respectively. Which i much prefer to an ungrepable processor name, as it allows me to match up shared object formats. – lee Feb 05 '20 at 15:09
27

Here's a hackish bit of code that should consistently find the name of the processor on the three platforms that I have any reasonable experience.

import os, platform, subprocess, re

def get_processor_name():
    if platform.system() == "Windows":
        return platform.processor()
    elif platform.system() == "Darwin":
        os.environ['PATH'] = os.environ['PATH'] + os.pathsep + '/usr/sbin'
        command ="sysctl -n machdep.cpu.brand_string"
        return subprocess.check_output(command).strip()
    elif platform.system() == "Linux":
        command = "cat /proc/cpuinfo"
        all_info = subprocess.check_output(command, shell=True).decode().strip()
        for line in all_info.split("\n"):
            if "model name" in line:
                return re.sub( ".*model name.*:", "", line,1)
    return ""
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
dbn
  • 13,144
  • 3
  • 60
  • 86
25

For an easy to use package, you can use cpuinfo.

Install as pip install py-cpuinfo

Use from the commandline: python -m cpuinfo

Code:

import cpuinfo
cpuinfo.get_cpu_info()['brand']
serv-inc
  • 35,772
  • 9
  • 166
  • 188
  • 4
    This gives a lot better CPU information on MacOS than `platform.processor()` does – Stephen Jun 15 '20 at 22:47
  • This does give the model name, but it's awefully slow because it computes other things you don't use here. – Nico Schlömer Mar 07 '22 at 16:08
  • @NicoSchlömer: somehow, python and awfully slow happens often together (unless there's some specifically optimized code, like numpy) ;-) – serv-inc Mar 08 '22 at 05:56
  • No, it's got nothing to do with Python. The author of the package decided to perform some computation alongside fetching the information from a file. – Nico Schlömer Mar 08 '22 at 09:08
20

There's some code here:

https://github.com/pydata/numexpr/blob/master/numexpr/cpuinfo.py

its very OS-dependent, so there's lots of if-branches. But it does work out all the CPU capabilities.

$ python cpuinfo.py 
CPU information: getNCPUs=2 has_mmx has_sse has_sse2 is_64bit is_Intel is_Pentium is_PentiumIV

For linux it looks in /proc/cpuinfo and tries using uname. For Windows it looks like it uses the registry.

To get the [first] processor name using this module:

>>> import cpuinfo
>>> cpuinfo.cpu.info[0]['model name']
'Intel(R) Pentium(R) 4 CPU 3.60GHz'

If its got more than one processor, then the elements of cpuinfo.cpu.info will have their names. I don't think I've ever seen a PC with two different processors though (not since the 80's when you could get a Z80 co-processor for your 6502 CPU BBC Micro...)

serv-inc
  • 35,772
  • 9
  • 166
  • 188
Spacedman
  • 92,590
  • 12
  • 140
  • 224
16

I tried out various solutions here. cat /proc/cpuinf gives a huge amount of output for a multicore machine, many pages long, platform.processor() seems to give you very little. Using Linux and Python 3, the following returns quite a useful summary of about twenty lines:

import subprocess
print((subprocess.check_output("lscpu", shell=True).strip()).decode())
cardamom
  • 6,873
  • 11
  • 48
  • 102
5

Working code (let me know if this doesn't work for you):

import platform, subprocess

def get_processor_info():
    if platform.system() == "Windows":
        return platform.processor()
    elif platform.system() == "Darwin":
        return subprocess.check_output(['/usr/sbin/sysctl', "-n", "machdep.cpu.brand_string"]).strip()
    elif platform.system() == "Linux":
        command = "cat /proc/cpuinfo"
        return subprocess.check_output(command, shell=True).strip()
    return ""
Phil L.
  • 2,637
  • 1
  • 17
  • 11
  • In python3 `subprocess` won't return a `str` but a `byte`. You have to convert it into a `str` with `your_byte.decode('utf-8')`. For example, for Darwin the code would be `model = subprocess.check_output(["/usr/sbin/sysctl", "-n", "machdep.cpu.brand_string"]).strip() ; return model.decode('utf-8')`. – lenooh Mar 09 '18 at 17:00
4

The if-cases for Windows i.e platform.processor() just gives the description or family name of the processor e.g. Intel64 Family 6 Model 60 Stepping 3.

I used:

  if platform.system() == "Windows":
        family = platform.processor()
        name = subprocess.check_output(["wmic","cpu","get", "name"]).strip().split("\n")[1]
        return ' '.join([name, family])

to get the actual cpu model which is the the same output as the if-blocks for Darwin and Linux, e.g. Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz Intel64 Family 6 Model 60 Stepping 3, GenuineIntel

oche
  • 939
  • 10
  • 19
3

[Answer]: this works the best

 import cpuinfo
 cpuinfo.get_cpu_info()['brand_raw'] # get only the brand name

or

 import cpuinfo
 cpuinfo.get_cpu_info()

To get all info about the cpu

{'python_version': '3.7.6.final.0 (64 bit)',
 'cpuinfo_version': [7, 0, 0],
 'cpuinfo_version_string': '7.0.0',
 'arch': 'X86_64',
 'bits': 64,
 'count': 2,
 'arch_string_raw': 'x86_64',
 'vendor_id_raw': 'GenuineIntel',
 'brand_raw': 'Intel(R) Xeon(R) CPU @ 2.00GHz',
 'hz_advertised_friendly': '2.0000 GHz',
 'hz_actual_friendly': '2.0002 GHz',
 'hz_advertised': [2000000000, 0],
 'hz_actual': [2000176000, 0],
 'stepping': 3,
 'model': 85,
 'family': 6,
 'flags': ['3dnowprefetch',
  'abm',
  'adx', ...more
Biplob Das
  • 2,818
  • 21
  • 13
2

Looks like the missing script in @Spacedman answer is here:

https://github.com/pydata/numexpr/blob/master/numexpr/cpuinfo.py

It is patched to work with Python 3.

>python cpuinfo.py
CPU information: CPUInfoBase__get_nbits=32 getNCPUs=2 has_mmx is_32bit is_Intel is_i686

The structure of data is indeed OS-dependent, on Windows it looks like this:

>python -c "import cpuinfo, pprint; pprint.pprint(cpuinfo.cpu.info[0])"
{'Component Information': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00',
 'Configuration Data': '\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00',
 'Family': 6,
 'FeatureSet': 2687451135L,
 'Identifier': u'x86 Family 6 Model 23 Stepping 10',
 'Model': 23,
 'Platform ID': 128,
 'Previous Update Signature': '\x00\x00\x00\x00\x0c\n\x00\x00',
 'Processor': '0',
 'ProcessorNameString': u'Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz',
 'Stepping': 10,
 'Update Signature': '\x00\x00\x00\x00\x0c\n\x00\x00',
 'Update Status': 2,
 'VendorIdentifier': u'GenuineIntel',
 '~MHz': 2394}

On Linux it is different:

# python -c "import cpuinfo, pprint; pprint.pprint(cpuinfo.cpu.info[0])"
{'address sizes': '36 bits physical, 48 bits virtual',
 'apicid': '0',
 'bogomips': '6424.11',
 'bugs': '',
 'cache size': '2048 KB',
 'cache_alignment': '128',
 'clflush size': '64',
 'core id': '0',
 'cpu MHz': '2800.000',
 'cpu cores': '2',
 'cpu family': '15',
 'cpuid level': '6',
 'flags': 'fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm const
ant_tsc pebs bts nopl pni dtes64 monitor ds_cpl est cid cx16 xtpr pdcm lahf_lm',
 'fpu': 'yes',
 'fpu_exception': 'yes',
 'initial apicid': '0',
 'microcode': '0xb',
 'model': '6',
 'model name': 'Intel(R) Pentium(R) D CPU 3.20GHz',
 'physical id': '0',
 'power management': '',
 'processor': '0',
 'siblings': '2',
 'stepping': '5',
 'uname_m': 'x86_64',
 'vendor_id': 'GenuineIntel',
 'wp': 'yes'}
anatoly techtonik
  • 19,847
  • 9
  • 124
  • 140
0

For Linux, and backwards compatibility with Python (not everyone has cpuinfo), you can parse through /proc/cpuinfo directly. To get the processor speed, try:

# Take any float trailing "MHz", some whitespace, and a colon.
speeds = re.search("MHz\s*: (\d+\.?\d*)", cpuinfo_content)

Note the necessary use of \s for whitespace.../proc/cpuinfo actually has tab characters and I toiled for hours working with sed until I came up with:

sed -rn 's/cpu MHz[ \t]*: ([0-9]+\.?[0-9]*)/\1/gp' /proc/cpuinfo

I lacked the \t and it drove me mad because I either matched the whole file or nothing.

Try similar regular expressions for the other fields you need:

# Take any string after the specified field name and colon.
re.search("field name\s*: (.+)", cpuinfo_content)