كيفية معرفة عدد وحدات المعالجة المركزية (CPUs) باستخدام بايثون

StackOverflow https://stackoverflow.com/questions/1006289

  •  06-07-2019
  •  | 
  •  

سؤال

أريد معرفة عدد وحدات المعالجة المركزية (CPUs) الموجودة على الجهاز المحلي باستخدام Python.يجب أن تكون النتيجة user/real كما الإخراج بواسطة time(1) عند استدعائها باستخدام برنامج مخصص لمساحة المستخدم فقط.

هل كانت مفيدة؟

المحلول 2

إذا كنت مهتما في عدد من المعالجات <م> متاح إلى العملية الحالية، لديك للتحقق <لأ href = "http://man7.org/linux/man-pages/man7 /cpuset.7.html "يختلط =" noreferrer "> cpuset أولا. خلاف ذلك (أو إذا cpuset ليس قيد الاستخدام)، multiprocessing.cpu_count() هي الطريقة للذهاب في بيثون 2.6 وأحدث. الأسلوب التالي يرتد إلى بضعة طرق بديلة في الإصدارات القديمة من بيثون:

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')

نصائح أخرى

إذا كان لديك الثعبان مع النسخة> = 2.6 يمكنك ببساطة استخدام

import multiprocessing

multiprocessing.cpu_count()

http://docs.python.org/library/multiprocessing.html# multiprocessing.cpu_count

وثمة خيار آخر هو استخدام المكتبة psutil ، التي تتحول دائما مفيدة في هذه الحالات:

>>> import psutil
>>> psutil.cpu_count()
2

وهذا يجب أن تعمل على أي منصة بدعم من psutil (يونيكس وويندوز).

لاحظ أنه في بعض المناسبات multiprocessing.cpu_count قد يثير NotImplementedError بينما psutil سوف تكون قادرة على الحصول على عدد من وحدات المعالجة المركزية. وهذا ببساطة لأن psutil أولا محاولة استخدام نفس التقنيات التي يستخدمها multiprocessing و، إذا كانت هذه يفشل، ويستخدم أيضا تقنيات أخرى.

في بيثون 3.4+: os.cpu_count ()

ويتم تنفيذ multiprocessing.cpu_count() من حيث هذه الوظيفة ولكن يثير NotImplementedError لو عاد os.cpu_count() None ( "لا يمكن تحديد عدد وحدات المعالجة المركزية").

import os

print(os.cpu_count())

منصة مستقلة:

psutil.cpu_count(منطقي=خطأ)

https://github.com/giampaolo/psutil/blob/master/INSTALL.rst

وmultiprocessing.cpu_count() سيعود عدد من وحدات المعالجة المركزية منطقية، لذلك إذا كان لديك وحدة المعالجة المركزية رباعية النوى مع توازي، فإنه سيعود 8. إذا كنت ترغب في عدد من وحدات المعالجة المركزية المادية، استخدم الارتباطات الثعبان لhwloc:

#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
تم تصميم

وhwloc أن تكون أنظمة تشغيل هو عبر المحمولة وأبنية.

len(os.sched_getaffinity(0)) هو ما تريده عادة

https://docs.python.org/3/library/os.html#os.sched_getaffinity

os.sched_getaffinity(0) (أضيف في Python 3) يُرجع مجموعة وحدات المعالجة المركزية المتاحة مع الأخذ في الاعتبار sched_setaffinity استدعاء نظام لينكس, ، مما يحد من وحدات المعالجة المركزية (CPU) التي يمكن تشغيل العملية وأطفالها عليها.

0 يعني الحصول على قيمة العملية الحالية.ترجع الدالة أ set() من وحدات المعالجة المركزية المسموح بها، وبالتالي الحاجة إلى len().

multiprocessing.cpu_count() من ناحية أخرى، تقوم فقط بإرجاع العدد الإجمالي لوحدات المعالجة المركزية الفعلية.

الفرق مهم بشكل خاص لأن بعض أنظمة إدارة المجموعات مثل منصة LSF الحد من استخدام وحدة المعالجة المركزية للمهمة مع sched_getaffinity.

لذلك، إذا كنت تستخدم multiprocessing.cpu_count(), ، قد يحاول البرنامج النصي الخاص بك استخدام عدد أكبر من النوى مما هو متاح، مما قد يؤدي إلى التحميل الزائد وانتهاء المهلات.

يمكننا أن نرى الفرق بشكل ملموس من خلال تقييد التقارب مع taskset جدوى.

على سبيل المثال، إذا قمت بتقييد لغة Python على نواة واحدة فقط (الأساسية 0) في نظامي المكون من 16 نواة:

taskset -c 0 ./main.py

مع البرنامج النصي للاختبار:

main.py

#!/usr/bin/env python3

import multiprocessing
import os

print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))

ثم الإخراج هو:

16
1

nproc يحترم التقارب بشكل افتراضي:

taskset -c 0 nproc

المخرجات:

1

و man nproc يجعل ذلك واضحًا تمامًا:

طباعة عدد وحدات المعالجة المتوفرة

nproc لديه --all إشارة للحالة الأقل شيوعًا التي تريد الحصول على عدد وحدة المعالجة المركزية الفعلية:

taskset -c 0 nproc --all

الجانب السلبي الوحيد لهذه الطريقة هو أنها تبدو وكأنها تعمل بنظام UNIX فقط.من المفترض أن يكون لدى Windows واجهة برمجة تطبيقات تقارب مماثلة، ربما SetProcessAffinityMask, ، لذلك أتساءل لماذا لم يتم نقله.لكني لا أعرف شيئا عن ويندوز.

تم الاختبار في Ubuntu 16.04 وPython 3.5.2.

لا يمكن معرفة كيفية إضافة إلى رمز أو الرد على الرسالة ولكن هنا دعم جيثون التي يمكنك تك الدخول قبل تتخلى عن:

# jython
try:
    from java.lang import Runtime
    runtime = Runtime.getRuntime()
    res = runtime.availableProcessors()
    if res > 0:
        return res
except ImportError:
    pass

ويمكنك أيضا استخدام "joblib" لهذا الغرض.

import joblib
print joblib.cpu_count()

وهذه الطريقة سوف تعطيك عدد من وحدات المعالجة المركزية في النظام. يحتاج joblib ليتم تثبيتها على الرغم من. ويمكن الاطلاع على مزيد من المعلومات حول joblib هنا https://pythonhosted.org/joblib/parallel.html

وبدلا من ذلك يمكنك استخدام numexpr مجموعة من الثعبان. لديها الكثير من وظائف بسيطة مفيدة للحصول على معلومات حول وحدة المعالجة المركزية النظام.

import numexpr as ne
print ne.detect_number_of_cores()

تمنحك هذه عدد وحدات المعالجة المركزية ذات الخيوط العالية

  1. multiprocessing.cpu_count()
  2. os.cpu_count()

تمنحك هذه عدد وحدة المعالجة المركزية للجهاز الظاهري

  1. psutil.cpu_count()
  2. numexpr.detect_number_of_cores()

يهم فقط إذا كنت تعمل على الأجهزة الافتراضية.

وثمة خيار آخر إذا لم يكن لديك بيثون 2.6:

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top