পাইথন ব্যবহার করে সিপিইউগুলির সংখ্যা কীভাবে সন্ধান করতে হবে


535

পাইথন ব্যবহার করে স্থানীয় মেশিনে সিপিইউগুলির সংখ্যা জানতে চাই। একটি অনুকূল স্কেলিং ব্যবহারকারী-কেবলমাত্র প্রোগ্রামের সাথে ডাকা হলে user/realফলাফলটি আউটপুট হিসাবে হওয়া উচিত time(1)


3
আপনার সিপুসেটগুলি (লিনাক্সে) মাথায় রাখা উচিত। আপনি যদি কোনও সিপুসেটে থাকেন তবে নীচের সমাধানগুলি আপনার সিস্টেমে রিয়েল সিপিইউগুলির সংখ্যা দেবে, আপনার প্রক্রিয়াটির জন্য উপলব্ধ সংখ্যাটি নয়। /proc/<PID>/statusকিছু লাইন রয়েছে যা আপনাকে বর্তমান সিপুজেটে সিপিইউ সংখ্যা বলে: দেখুন Cpus_allowed_list
wpoely86

উত্তর:


853

আপনার কাছে সংস্করণ> = 2.6 সহ অজগর থাকলে আপনি সহজেই ব্যবহার করতে পারেন

import multiprocessing

multiprocessing.cpu_count()

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


4
মাল্টিপ্রসেসিংটি 3.x
লিটলবাই ব্লু

3
আমি যুক্ত করতে চাই যে এটি আয়রনপাইথনে কাজ করে না যা একটি নোটিপ্লিমেন্টেড এরির উত্থাপন করে।
ম্যাথিয়াস

1
এটি উপলব্ধ সিপিইউগুলির সংখ্যা দেয় ... প্রোগ্রামটি ব্যবহারে নয়!
এএমসি

25
পাইথন 3.6.2 এ আমি কেবল ব্যবহার করতে পারিos.cpu_count()
অ্যাকিলিস

4
এছাড়াও, নীচে উল্লিখিত হিসাবে, এই গণনাটিতে "ভার্চুয়াল" হাইপারথ্রেডেড সিপাস অন্তর্ভুক্ত থাকতে পারে, যা আপনি সিপিইউ-নিবিড় কাজগুলির সময় নির্ধারণের সময় যদি চান তা নাও হতে পারে।
ক্রিস্টোফার নাপিত

185

আপনি যদি আপনার বর্তমান প্রক্রিয়াটিতে উপলব্ধ প্রসেসরের সংখ্যার প্রতি আগ্রহী হন , আপনাকে প্রথমে সিপুয়েসেট পরীক্ষা করতে হবে । অন্যথায় (বা সিপুসেট ব্যবহার না হলে), multiprocessing.cpu_count()পাইথন ২.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')

সাম্প্রতিক উবুন্টু চলমান একটি ম্যাকপ্রোতে 1,0, এইচপি ল্যাপটপে সাম্প্রতিক ডেবিয়ান চালাচ্ছেন এবং পুরাতন উবুন্টু চালাচ্ছেন একটি পুরাতন ইমচাইন-এ, সিপাস_বিহীন ফলাফল /proc/self/statusযথাক্রমে ff, f এবং f --- 8, 4 এর সাথে সম্পর্কিত এবং 4 আপনার (সঠিক) গণিতে তবে সিপিইউগুলির আসল সংখ্যা যথাক্রমে 4, 2 এবং 1। আমি দেখতে পেয়েছি যে "প্রসেসর" শব্দটির সংখ্যার সংখ্যা গণনা /proc/cpuinfoকরা আরও ভাল উপায় হতে পারে। (বা আমার কি প্রশ্নটি ভুল আছে?)
মাইক ও'কনর

1
আরও কিছু গবেষণার মাধ্যমে --- যদি এটি "গুগলিং" সম্পর্কে বলা যেতে পারে --- আমি এটির ব্যবহার থেকে জানতে পারি /proc/cpuinfoযদি প্রতিটি "প্রসেসর" এর তালিকার কোনও একটির জন্য আপনি "ভাই-বোন" "সিপিইউ কোর" দ্বারা গুণান আপনি আপনার "সিপাস_নীলিত" নম্বর পাবেন। এবং আমি জড়ো করেছি যে ভাইবোনরা হাইপার-থ্রেডিংয়ের বিষয়ে উল্লেখ করে, সুতরাং আপনার "ভার্চুয়াল" এর জন্য উল্লেখ। তবে সত্যটি এখনও অব্যাহত রয়েছে যে আপনার "সিপাস_নীলিত" নম্বরটি আমার ম্যাকপ্রোতে 8 টি রয়েছে যদিও আপনার multiprocessing.cpu_count()উত্তর 4 My আমার নিজেরও open('/proc/cpuinfo').read().count('processor')4 টি, শারীরিক কোরের সংখ্যা (দুটি ডুয়াল-কোর প্রসেসর) উত্পাদন করে।
মাইক ও'কনোর

1
open('/proc/self/status').read()ফাইলটি বন্ধ করতে ভুলে যায় with open('/proc/self/status') as f: f.read()পরিবর্তে ব্যবহার করুন
টাইমডিলস

4
os.cpu_count()
goetzc

1
@ এমসিগ্রিগোর এক্ষেত্রে এটি গ্রহণযোগ্য, সম্মতিযুক্ত, কেবল ফাইল হ্যান্ডলগুলি উন্মুক্ত রেখে দেওয়া হচ্ছে বলে আমি মনে করি ঠিক আছে যদি আপনি দীর্ঘকাল চলমান ডিমন / প্রক্রিয়াটি লিখছেন না; যা আমি আশঙ্কা করি এটি ওএসের সর্বাধিক উন্মুক্ত ফাইল হ্যান্ডলগুলি মারতে পারে। প্রক্রিয়া শেষ হওয়ার আগে পুনরায় পড়া দরকার এমন কোনও ফাইলে লেখার সময় এটি আরও খারাপ but তবুও ব্যবহারের অভ্যাস থাকা ভাল ধারণাwithআপনার যখন প্রয়োজন হয় এমন কোনও ক্ষেত্রে মুখোমুখি হন তখনও ।
টিমডিএলস

91

আরেকটি বিকল্প হ'ল psutilগ্রন্থাগারটি ব্যবহার করা , যা সর্বদা এই পরিস্থিতিতে কার্যকর হয়:

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

এটি psutil(ইউনিক্স এবং উইন্ডোজ) সমর্থিত যে কোনও প্ল্যাটফর্মে কাজ করা উচিত ।

কিছু অনুষ্ঠানে লক্ষ্য করুন multiprocessing.cpu_countNotImplementedError সময় বাড়াতে psutilপারে সিপিইউগুলির সংখ্যা অর্জন করতে সক্ষম। এটি কেবল কারণ এটির জন্য psutilপ্রথম ব্যবহৃত কৌশলগুলি ব্যবহার করার চেষ্টা করে multiprocessingএবং যদি এটি ব্যর্থ হয় তবে এটি অন্যান্য কৌশলও ব্যবহার করে।


4
এটি সত্যিই খুব ভাল, এটি বিবেচনা করে যে ব্যবহৃত পদ্ধতিটি সিপিইউ কোরগুলি যৌক্তিক আকরিক শারীরিক বিষয়গুলি খুঁজে পেতে পারে। psutil.cpu_count(logical = True)
ডেভিলহুন্টার

হাই @ বাকুরিউ, পিউইউ কোরের একটি নির্দিষ্ট প্রক্রিয়া দ্বারা psutil ব্যবহার করে নম্বর পাওয়ার কোনও উপায় আছে কি?
সাইচাঁদ

আমার ডেভেল আই 7-8700 উইন্ডোজে ডেভিডহান্টার psutil.cpu_count()12 দেয় (এটি হাইপারথ্রেডিং সহ একটি 6-কোর সিপিইউ)। এটির কারণ হ'ল ডিফল্ট যুক্তিটি logicalসত্য, সুতরাং psutil.cpu_count(logical = False)শারীরিক কোরের সংখ্যা পেতে আপনাকে স্পষ্টতই লিখতে হবে।
অস্কারভ্যানএল

52

পাইথনে ৩.৪++: os.cpu_count ()

multiprocessing.cpu_count()এই ফাংশন পরিপ্রেক্ষিতে বাস্তবায়িত কিন্তু উত্থাপন করা হয় NotImplementedErrorযদি os.cpu_count()আয় None( "সিপিইউ সংখ্যা নির্ধারণ করতে পারি না")।


4
এর ডকুমেন্টেশনও দেখুন cpu_countlen(os.sched_getaffinity(0))উদ্দেশ্য উপর নির্ভর করে ভাল হতে পারে।
অ্যালবার্ট

1
@ অ্যালবার্ট হ্যাঁ, সিস্টেমে সিপিইউগুলির সংখ্যা (যা os.cpu_count()ওপি জিজ্ঞাসা করে) বর্তমান প্রসেসের জন্য উপলব্ধ সিপিইউগুলির সংখ্যার চেয়ে পৃথক হতে পারে ( os.sched_getaffinity(0))।
jfs

আমি জানি. আমি অন্যান্য পাঠকদের জন্য এটি যুক্ত করতে চেয়েছিলাম, যারা এই পার্থক্যটি মিস করতে পারে তাদের কাছ থেকে আরও একটি সম্পূর্ণ ছবি পেতে get
অ্যালবার্ট

1
এছাড়াও: os.sched_getaffinity(0)হয় না বাসদ উপলব্ধ তাই ব্যবহার, os.cpu_count()প্রয়োজন হয় (অন্যান্য বাহ্যিক গ্রন্থাগার ছাড়া যে,)।
কমেটসং

1
এটি নোট করা উচিত os.sched_getaffinity উইন্ডোজে উপলব্ধ বলে মনে হয় না।
manu3d

47

len(os.sched_getaffinity(0)) আপনি সাধারণত যা চান

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

os.sched_getaffinity(0)(পাইথন 3 এ যুক্ত) sched_setaffinityলিনাক্স সিস্টেম কল বিবেচনা করে উপলব্ধ সিপিইউগুলির সেট প্রদান করে , যা কোন প্রসেসের সিপিইউগুলিকে সীমাবদ্ধ করে এবং এর শিশুরা চালাতে পারে।

0মানে বর্তমান প্রক্রিয়াটির জন্য মান পাওয়া। ফাংশনটি set()অনুমোদিত সিপিইউগুলি প্রদান করে, যাতে এটির প্রয়োজন হয় len()

multiprocessing.cpu_count() অন্যদিকে কেবল শারীরিক সিপিইউগুলির মোট সংখ্যা প্রদান করে।

পার্থক্যটি বিশেষভাবে গুরুত্বপূর্ণ কারণ নির্দিষ্ট ক্লাস্টার ম্যানেজমেন্ট সিস্টেমগুলি যেমন প্ল্যাটফর্ম এলএসএফ সীমাবদ্ধ করে চাকরি সিপিইউ ব্যবহার করে sched_getaffinity

অতএব, আপনি যদি ব্যবহার করেন তবে multiprocessing.cpu_count()আপনার স্ক্রিপ্টটি উপলভ্যতার চেয়ে আরও বেশি উপায় ব্যবহার করার চেষ্টা করতে পারে যা ওভারলোড এবং সময়সীমা সরিয়ে নিতে পারে।

tasksetইউটিলিটির সাথে সখ্যতা সীমাবদ্ধ করে আমরা পার্থক্যটি দৃ concrete়তার সাথে দেখতে পারি ।

উদাহরণস্বরূপ, যদি আমি আমার 16 টি কোর সিস্টেমে পাইথনকে কেবল 1 কোর (কোর 0) এ সীমাবদ্ধ রাখি:

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

এই পদ্ধতির একমাত্র নেতিবাচকতা এটি কেবল ইউনিক্স হিসাবে উপস্থিত হয়। আমার ধারণা ছিল উইন্ডোজের অবশ্যই একটি অনুরূপ অ্যাফিনিটি এপিআই থাকতে হবে SetProcessAffinityMask, তাই কেন আমি এটি পোর্ট করা হয়নি তা অবাক করি। তবে আমি উইন্ডোজ সম্পর্কে কিছুই জানি না।

উবুন্টু 16.04, পাইথন 3.5.3।


3
শুধুমাত্র ইউনিক্সে উপলব্ধ।
ক্রিস্টোফার নাপিত

উত্তরটিতে যোগ করা তথ্যের জন্য ক্রিস্টোফারবার্বারকে ধন্যবাদ জানাই।
সিরো সান্তিলি 郝海东 冠状 病 六四 事件 法轮功

33

স্বাধীন প্ল্যাটফর্ম:

psutil.cpu_count (লজিক্যাল = মিথ্যা)

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


4
একটি লজিকাল সিপিইউ এবং কোন যৌক্তিক নয়, তার মধ্যে পার্থক্য কী? আমার ল্যাপটপে: psutil.cpu_count(logical=False) #4 psutil.cpu_count(logical=True) #8এবংmultiprocessing.cpu_count() #8
ব্যবহারকারী 305883

1
@ ব্যবহারকারী 305883 ধরে নিয়ে আপনি একটি x86 সিপিইউ করেছেন, আপনার এই মেশিনে হাইপারথ্রেডিং রয়েছে, অর্থাত্ প্রতিটি শারীরিক কোর দুটি হাইপারথ্রেড ('লজিকাল' কোর) এর সাথে মিলে যায়। হাইপারথ্রেডিং শারীরিক কোরটি থ্রেড বি থেকে নির্দেশাবলী কার্যকর করতে ব্যবহার করতে অনুমতি দেয় যখন এর অংশগুলি থ্রেড এ এর ​​জন্য নিষ্ক্রিয় থাকে (যেমন ক্যাশে বা স্মৃতি থেকে ডেটা আনার জন্য অপেক্ষা করা হয়)। আপনার কোডের উপর নির্ভর করে একজন অতিরিক্ত কোর ব্যবহারের এক বা কয়েক দশক পার্সেন্ট পেতে পারেন তবে এটি প্রকৃত শারীরিক কোরের কর্মক্ষমতা থেকে অনেক নীচে।
আন্দ্রে হল্জনার

23

এগুলি আপনাকে হাইপারথ্রেডেড সিপিইউ গণনা দেয়

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

এগুলি আপনাকে ভার্চুয়াল মেশিনের সিপিইউ গণনা দেয়

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

আপনি যদি ভিএমগুলিতে কাজ করেন তবেই তা গুরুত্বপূর্ণ।


আসলে তা না. যেমনটি উল্লেখ করা হয়েছে, os.cpu_count()এবং multiprocessing.cpu_count()হাইপারথ্রেডেড সিপিইউ গণনাগুলি ফিরিয়ে দেবে, প্রকৃত শারীরিক সিপু গণনা নয়।
ক্রিস্টোফার নাপিত

2
হ্যাঁ. আমি উচ্চারিত। এটি সাধারণত # কোরের x x 2 এর অর্থ হ'ল আপনি যদি ভার্চুয়াল মেশিনে থাকেন তবে এটি 8 টি কোর তৈরি হয়েছিল, তবে আপনার হোস্ট মেশিনটি শারীরিকভাবে 20 কোরের, প্রথম কমান্ড আপনাকে 20 প্রদান করবে, দ্বিতীয় সেট কমান্ড দেবে 8.
ইয়াংলিউ 2

21

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 ওএস এবং আর্কিটেকচার জুড়ে পোর্টেবল হতে ডিজাইন করা হয়েছে।


এই ক্ষেত্রে, আমি লজিকাল সিপিইউগুলির সংখ্যা চাই (অর্থাত্ যদি এই প্রোগ্রামটি সত্যই ভালভাবে স্কেল করে তবে আমার কতগুলি থ্রেড শুরু করা উচিত) তবে উত্তরটি তবুও সহায়ক হতে পারে।
ফিহাগ

7
বাpsutil.cpu_count(logical=False)
টিমজামান

8

কোডটিতে কীভাবে যুক্ত করা বা বার্তার উত্তর দেওয়া যায় তা অনুমান করতে পারছি না তবে এখানে জাইথনের পক্ষে সমর্থন যা আপনি হাল ছেড়ে দেওয়ার আগে এটিকে মোকাবেলা করতে পারেন:

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

7

এটি আমাদের মধ্যে যারা বিভিন্ন ওএস / সিস্টেম ব্যবহার করে তাদের জন্য কাজ করতে পারে তবে সমস্ত বিশ্বের সেরা পেতে চায়:

import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
    workers = len(os.sched_getaffinity(0))

5

আপনি এই কাজের জন্য "জবলিব" ব্যবহার করতে পারেন।

import joblib
print joblib.cpu_count()

এই পদ্ধতিটি আপনাকে সিস্টেমে সিপাসের নম্বর দেবে। জবলিব যদিও ইনস্টল করা প্রয়োজন। জবলিব সম্পর্কিত আরও তথ্য এখানে পাওয়া যাবে https://pythonhosted.org/joblib/parallel.html

বিকল্পভাবে আপনি পাইথনের numexpr প্যাকেজটি ব্যবহার করতে পারেন। এটি সিস্টেম সিপিইউ সম্পর্কিত তথ্য পাওয়ার জন্য অনেকগুলি সহজ কার্যকারিতা রয়েছে।

import numexpr as ne
print ne.detect_number_of_cores()

জবলিব অন্তর্নিহিত মাল্টিপ্রসেসিং মডিউলটি ব্যবহার করে। এটির জন্য সরাসরি মাল্টিপ্রসেসিংয়ে কল করা ভাল।
ogrisel

1

আপনার কাছে পাইথন ২.6 না থাকলে অন্য একটি বিকল্প:

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")

2
ধন্যবাদ! এটি কেবল লিনাক্সে উপলভ্য, এবং ইতিমধ্যে আমার উত্তরে অন্তর্ভুক্ত ।
ফিলাগ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.