। নেট / সি # এর মাধ্যমে সিপিইউ কোরের সংখ্যাটি কীভাবে খুঁজে পাবেন?


317

.NET / C # এর মাধ্যমে কি কোনও উপায় আছে? সিপিইউ কোরের সংখ্যা বের করার ?

পিএস এটি একটি সোজা কোড প্রশ্ন, "আমার কি মাল্টি-থ্রেডিং ব্যবহার করা উচিত?" প্রশ্ন! :-)


7
কতগুলি কোর রয়েছে বা কতগুলি লজিকাল প্রসেসর রয়েছে তা আপনার জানতে হবে? কেবল একাধিক থ্রেড চালানোর জন্য, সম্ভবত যথেষ্ট যথেষ্ট, তবে এমন পরিস্থিতি রয়েছে যেখানে পার্থক্যটি গুরুত্বপূর্ণ হতে পারে।
কেভিন কিবলার

এটি করার নতুন উপায় আছে?
চাঁদরাত্রি

উত্তর:


477

প্রসেসরের সাথে সম্পর্কিত বিভিন্ন ধরণের তথ্য রয়েছে যা আপনি পেতে পারেন:

  1. শারীরিক প্রসেসরের সংখ্যা
  2. কোর সংখ্যা
  3. লজিকাল প্রসেসরের সংখ্যা।

এগুলি সব আলাদা হতে পারে; 2 টি ডুয়াল-কোর হাইপার-থ্রেডিং-সক্ষম প্রসেসর সহ একটি মেশিনের ক্ষেত্রে 2 টি ফিজিকাল প্রসেসর, 4 টি কোর এবং 8 লজিকাল প্রসেসর রয়েছে।

যৌক্তিক প্রসেসরের সংখ্যা এনভায়রনমেন্ট ক্লাসের মাধ্যমে পাওয়া যায় , তবে অন্যান্য তথ্য কেবল ডাব্লুএমআইয়ের মাধ্যমে পাওয়া যায় (এবং এটি কিছু সিস্টেমে পেতে আপনাকে কিছু হটফিক্স বা সার্ভিস প্যাক ইনস্টল করতে হতে পারে ):

আপনার প্রকল্পে রেফারেন্স যোগ করার বিষয়টি নিশ্চিত করুন System.Management.dll .NET কোর-এ, এটি একটি নিউগেট প্যাকেজ হিসাবে (কেবল উইন্ডোজের জন্য) উপলব্ধ।

শারীরিক প্রসেসর:

foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
    Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);
}

কোর:

int coreCount = 0;
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
{
    coreCount += int.Parse(item["NumberOfCores"].ToString());
}
Console.WriteLine("Number Of Cores: {0}", coreCount);

লজিকাল প্রসেসর:

Console.WriteLine("Number Of Logical Processors: {0}", Environment.ProcessorCount);

অথবা

foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
    Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);
}

প্রসেসরগুলি উইন্ডোজ থেকে বাদ:

আপনি উইন্ডোজ থেকে বাদ পড়েছেন (যেমন বুট সেটিংসের মাধ্যমে) এবং উপরোক্ত উপায়গুলি ব্যবহার করে সনাক্তযোগ্য নয় এমন প্রসেসরগুলি আবিষ্কার করতে setupapi.dll এ উইন্ডোজ এপিআই কলগুলিও ব্যবহার করতে পারেন । নীচের কোডটি লজিকাল প্রসেসরের মোট সংখ্যা দেয় (উইন্ডোজ থেকে বাদ দেওয়া হয়েছে এমনগুলি সহ, লজিকাল প্রসেসরের থেকে শারীরিক পার্থক্য কীভাবে করা যায় তা আমি বুঝতে পারি না):

static void Main(string[] args)
{
    int deviceCount = 0;
    IntPtr deviceList = IntPtr.Zero;
    // GUID for processor classid
    Guid processorGuid = new Guid("{50127dc3-0f36-415e-a6cc-4cb3be910b65}");

    try
    {
        // get a list of all processor devices
        deviceList = SetupDiGetClassDevs(ref processorGuid, "ACPI", IntPtr.Zero, (int)DIGCF.PRESENT);
        // attempt to process each item in the list
        for (int deviceNumber = 0; ; deviceNumber++)
        {
            SP_DEVINFO_DATA deviceInfo = new SP_DEVINFO_DATA();
            deviceInfo.cbSize = Marshal.SizeOf(deviceInfo);

            // attempt to read the device info from the list, if this fails, we're at the end of the list
            if (!SetupDiEnumDeviceInfo(deviceList, deviceNumber, ref deviceInfo))
            {
                deviceCount = deviceNumber;
                break;
            }
        }
    }
    finally
    {
        if (deviceList != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceList); }
    }
    Console.WriteLine("Number of cores: {0}", deviceCount);
}

[DllImport("setupapi.dll", SetLastError = true)]
private static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid,
    [MarshalAs(UnmanagedType.LPStr)]String enumerator,
    IntPtr hwndParent,
    Int32 Flags);

[DllImport("setupapi.dll", SetLastError = true)]
private static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet,
    Int32 MemberIndex,
    ref SP_DEVINFO_DATA DeviceInterfaceData);

[StructLayout(LayoutKind.Sequential)]
private struct SP_DEVINFO_DATA
{
    public int cbSize;
    public Guid ClassGuid;
    public uint DevInst;
    public IntPtr Reserved;
}

private enum DIGCF
{
    DEFAULT = 0x1,
    PRESENT = 0x2,
    ALLCLASSES = 0x4,
    PROFILE = 0x8,
    DEVICEINTERFACE = 0x10,
}

14
@ স্টেটিংজ্যাক: সত্য, তবে আমি আশা করি এটি খুব সুন্দর বিন্যাসে থাকত। যখন আপনাকে কাঁচা স্ট্রিংয়ের ক্যোয়ারী তৈরি করতে হয় তখন আবিষ্কারগুলি খুব কম।
কেভিন কিবলার

5
ডাব্লুএমআই কোড নির্মাতা মান আবিষ্কার এবং ক্যোয়ারী তৈরিতে সহায়তা করবে (এটি সি # / ভিবিএনটিতে স্টাবগুলিও তৈরি করতে পারে)।
স্টিংজি জ্যাক

4
এটি System.Management.dll এ রয়েছে। আপনি কি আপনার প্রকল্পে সেই সমাবেশটির একটি রেফারেন্স অন্তর্ভুক্ত করেছিলেন?
কেভিন কিবলার

2
উপরের কোডটিতে ছোটখাটো একের পর এক সমস্যা। যেহেতু deviceCountশূন্য-ভিত্তিক, মূল গণনাটি এই জাতীয় আউটপুট হওয়া উচিত:Console.WriteLine("Number of cores: {0}", deviceCount + 1);
ফ্রান্সিস লিটারিও

2
আপনি কি পরিচালন সামগ্রী এবং অনুসন্ধানকারীদের নিষ্পত্তি না করে সমস্যা সৃষ্টি করছেন না?
বেঞ্জামিন

205
Environment.ProcessorCount

[ডকুমেন্টেশন]


12
এতো সুন্দর আমি প্রায় চোখের জল ফেলছি। জবাবের জন্য থেক্স!
মিঃ গ্রেগলস

70
এটি লজিকাল প্রসেসরের সংখ্যা দেয়, কোরের সংখ্যা নয়।
কেভিন কিবলার

8
@ কেভিনকিবলার প্রশ্ন থেকে, আমি সন্দেহ করি যে ওপি পার্থক্য বুঝতে পারে না এবং আপনি যদি পার্থক্যটি জানেন না তবে এটি সম্ভবত আপনি চান।
গ্লেন মেইনার্ড

1
এটি অনেকগুলি মূল সিস্টেমে ভুল গণনাও প্রদান করে। হাইপার-থ্রেডিং সহ আমি দুটি ডোডেকা কোর প্রসেসর চালাচ্ছি, যা আমাকে মোট 48 লজিকাল প্রসেসর দেয়। Environment.ProcessorCountফলন 32.
অ্যালেন ক্লার্ক কোপল্যান্ড জুনিয়র

1
@ আলেকজান্ডারমোরো, হ্যাঁ এটি কয়েকটি মাল্টি সিপিইউ সার্ভারের সঠিক ফলাফল দিতে ব্যর্থ হবে। এটির জন্য একটি ঠিক আছে, তবে এখনও এটি পরীক্ষা করে দেখেনি।
দ্য লিজেন্ডারিকপি কোডার

35

ডাব্লুএমআই প্রশ্নগুলি ধীর গতির, সুতরাং নির্বাচন * ব্যবহার না করে কেবলমাত্র পছন্দসই সদস্য নির্বাচন করার চেষ্টা করুন।

নিম্নলিখিত কোয়েরিটি 3.4 এস নেয়:

foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())

যদিও এটির জন্য 0.122s লাগে:

foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())

1
আপনি কোন সিস্টেমে এটি চালাচ্ছেন? আমি একাধিক "নির্বাচন করুন *" প্রশ্নের ব্যবহার এবং তা লাগবে না যে কোন জায়গায় 3.4 কাছাকাছি সেকেন্ড, কম্পিউটার হাজার হাজার যে আমার সফটওয়্যারের উপর মোতায়েন হয় পরীক্ষিত। আমি একটি নির্বাচন করুন * কারণ আমি বস্তু থেকে একাধিক সম্পত্তি পাচ্ছি। তবে, আমি এটি কিছুটা আলাদা করি: নির্বাচন করুন * এ একটি অবজেক্টকোয়ারি তৈরি করুন; ম্যানেজমেন্টঅবজেক্ট কালেকশন পান; তারপরে ম্যানেজমেন্টঅবজেক্ট কালেকশনে ম্যানেজমেন্টঅজেক্টকে ভবিষ্যদ্বাণী করুন।
ডিজি

@ ডিজি: আপনি ঠিক বলেছেন, ক্যোরিটি নিজেই "সিলেক্ট *" দিয়ে খুব বেশি সময় নেয় না, কেবলমাত্র নাম্বারফোরসগুলির পরিবর্তে সমস্ত মানগুলি পুনরাবৃত্তি করলে নীচের ইনট পার্সিংটি ধীর হয়।
আলেক্স মারক্যাডার


10

এটি কীভাবে অন্তর্নিহিতভাবে অন্তর্নিহিতভাবে বলতে পারা যায় তা দেখার চেয়ে বরং আকর্ষণীয় ... এটি নীচের মতো "সরল":

namespace System.Threading
{
    using System;
    using System.Runtime.CompilerServices;

    internal static class PlatformHelper
    {
        private const int PROCESSOR_COUNT_REFRESH_INTERVAL_MS = 0x7530;
        private static volatile int s_lastProcessorCountRefreshTicks;
        private static volatile int s_processorCount;

        internal static bool IsSingleProcessor
        {
            get
            {
                return (ProcessorCount == 1);
            }
        }

        internal static int ProcessorCount
        {
            get
            {
                int tickCount = Environment.TickCount;
                int num2 = s_processorCount;
                if ((num2 == 0) || ((tickCount - s_lastProcessorCountRefreshTicks) >= 0x7530))
                {
                    s_processorCount = num2 = Environment.ProcessorCount;
                    s_lastProcessorCountRefreshTicks = tickCount;
                }
                return num2;
            }
        }
    }
}

6

সহজতম উপায় = পরিবেশEnvironment.ProcessorCount
থেকে অনুগামী। প্রসেসরকাউন্ট সম্পত্তি

using System;

class Sample 
{
    public static void Main() 
    {
        Console.WriteLine("The number of processors " +
            "on this computer is {0}.", 
            Environment.ProcessorCount);
    }
}

পদ্ধতি পরিবেশ। প্রসেসরাউন্ট কখনও কখনও ভুল ডেটা দেখায় ( স্ট্যাকওভারফ্লো.com/ জিজ্ঞাসাগুলি দেখুন / 27965962/… দেখুন )
কনস্ট্রাক্টর

4

.NET ফ্রেমওয়ার্ক উত্স থেকে

এছাড়াও আপনি সঙ্গে এটি পেতে পারেন PInvoke উপরKernel32.dll

নিম্নলিখিত কোডটি SystemInfo.csসিস্টেম থেকে কম বা কম আসছে coming এখানে অবস্থিত ওয়েব উত্স :

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_INFO
{
  public ushort wProcessorArchitecture;
  public ushort wReserved;
  public uint dwPageSize;
  public IntPtr lpMinimumApplicationAddress;
  public IntPtr lpMaximumApplicationAddress;
  public IntPtr dwActiveProcessorMask;
  public uint dwNumberOfProcessors;
  public uint dwProcessorType;
  public uint dwAllocationGranularity;
  public ushort wProcessorLevel;
  public ushort wProcessorRevision;
}

internal static class SystemInfo 
{
    static int _trueNumberOfProcessors;
    internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);    

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    internal static extern void GetSystemInfo(out SYSTEM_INFO si);

    [DllImport("kernel32.dll")]
    internal static extern int GetProcessAffinityMask(IntPtr handle, out IntPtr processAffinityMask, out IntPtr systemAffinityMask);

    internal static int GetNumProcessCPUs()
    {
      if (SystemInfo._trueNumberOfProcessors == 0)
      {
        SYSTEM_INFO si;
        GetSystemInfo(out si);
        if ((int) si.dwNumberOfProcessors == 1)
        {
          SystemInfo._trueNumberOfProcessors = 1;
        }
        else
        {
          IntPtr processAffinityMask;
          IntPtr systemAffinityMask;
          if (GetProcessAffinityMask(INVALID_HANDLE_VALUE, out processAffinityMask, out systemAffinityMask) == 0)
          {
            SystemInfo._trueNumberOfProcessors = 1;
          }
          else
          {
            int num1 = 0;
            if (IntPtr.Size == 4)
            {
              uint num2 = (uint) (int) processAffinityMask;
              while ((int) num2 != 0)
              {
                if (((int) num2 & 1) == 1)
                  ++num1;
                num2 >>= 1;
              }
            }
            else
            {
              ulong num2 = (ulong) (long) processAffinityMask;
              while ((long) num2 != 0L)
              {
                if (((long) num2 & 1L) == 1L)
                  ++num1;
                num2 >>= 1;
              }
            }
            SystemInfo._trueNumberOfProcessors = num1;
          }
        }
      }
      return SystemInfo._trueNumberOfProcessors;
    }
}

2
এটি চেষ্টা করেছে, তবে এটি যৌক্তিক প্রসেসরের সংখ্যা প্রদান করে - যা পরিবেশকে ডেকে আনা একই ফলাফল। প্রসেসরকাউন্ট।
বব ব্রায়ান

1

একটি বিকল্প হ'ল রেজিস্ট্রি থেকে ডেটা পড়া। বিষয়টির উপর এমএসডিএন নিবন্ধ: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx )

প্রসেসরগণ, আমি বিশ্বাস করি যে এখানে অবস্থিত হতে পারে, HKEY_LOCAL_MACHINE AR হার্ডওয়ার ES বিবরণ \ সিস্টেম \ কেন্দ্রীয় প্রসেসর

    private void determineNumberOfProcessCores()
    {
        RegistryKey rk = Registry.LocalMachine;
        String[] subKeys = rk.OpenSubKey("HARDWARE").OpenSubKey("DESCRIPTION").OpenSubKey("System").OpenSubKey("CentralProcessor").GetSubKeyNames();

        textBox1.Text = "Total number of cores:" + subKeys.Length.ToString();
    }

আমি যুক্তিসঙ্গতভাবে নিশ্চিত যে বেশিরভাগ সিস্টেমে রেজিস্ট্রি এন্ট্রি থাকবে।

যদিও আমি আমার 0.02 ডলার নিক্ষেপ করব।


এটি এনভায়রনমেন্টে ইতিমধ্যে উপলব্ধ প্রসেসরের সংখ্যা দেবে ro প্রসেসরকাউন্ট, প্রতিটি প্রসেসরের জন্য কোরের সংখ্যা পাওয়ার জন্য এই জাতীয় কোনও উপায় আছে কি?
আর্মেন

0

নিম্নলিখিত প্রোগ্রামটি উইন্ডোজ মেশিনের লজিকাল এবং শারীরিক কোরগুলি মুদ্রণ করে।

#define STRICT
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <omp.h>

template<typename T>
T *AdvanceBytes(T *p, SIZE_T cb)
{
 return reinterpret_cast<T*>(reinterpret_cast<BYTE *>(p) + cb);
}

class EnumLogicalProcessorInformation
{
public:
 EnumLogicalProcessorInformation(LOGICAL_PROCESSOR_RELATIONSHIP Relationship)
  : m_pinfoBase(nullptr), m_pinfoCurrent(nullptr), m_cbRemaining(0)
 {
  DWORD cb = 0;
  if (GetLogicalProcessorInformationEx(Relationship,
                                       nullptr, &cb)) return;
  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return;

  m_pinfoBase =
   reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>
                                     (LocalAlloc(LMEM_FIXED, cb));
  if (!m_pinfoBase) return;

  if (!GetLogicalProcessorInformationEx(Relationship, 
                                        m_pinfoBase, &cb)) return;

  m_pinfoCurrent = m_pinfoBase;
  m_cbRemaining = cb;
 }

 ~EnumLogicalProcessorInformation() { LocalFree(m_pinfoBase); }

 void MoveNext()
 {
  if (m_pinfoCurrent) {
   m_cbRemaining -= m_pinfoCurrent->Size;
   if (m_cbRemaining) {
    m_pinfoCurrent = AdvanceBytes(m_pinfoCurrent,
                                  m_pinfoCurrent->Size);
   } else {
    m_pinfoCurrent = nullptr;
   }
  }
 }

 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *Current()
                                         { return m_pinfoCurrent; }
private:
 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *m_pinfoBase;
 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *m_pinfoCurrent;
 DWORD m_cbRemaining;
};


int __cdecl main(int argc, char **argv)
{
  int numLogicalCore = 0;
  int numPhysicalCore = 0;

  for (EnumLogicalProcessorInformation enumInfo(RelationProcessorCore);
      auto pinfo = enumInfo.Current(); enumInfo.MoveNext()) 
  {
      int numThreadPerCore = (pinfo->Processor.Flags == LTP_PC_SMT) ? 2 : 1;
      // std::cout << "thread per core: "<< numThreadPerCore << std::endl;
      numLogicalCore += numThreadPerCore;
      numPhysicalCore += 1;
  }

  printf ("Number of physical core = %d , Number of Logical core = %d \n", numPhysicalCore, numLogicalCore );

 char c = getchar(); /* just to wait on to see the results in the command prompt */
 return 0;
}

/*
I tested with Intel Xeon four cores with hyper threading and here is the result
Number of physical core = 4 , Number of Logical core = 8
*/

6
এই প্রশ্নটি ট্যাগ করা। নেট; আপনার কোড। নেট কোড নয়।
ওয়াই হা লি

-1

আমি একই জিনিসটি খুঁজছিলাম কিন্তু আমি কোনও ন্যুগেট বা সার্ভিসপ্যাক ইনস্টল করতে চাই না, সুতরাং আমি এই সমাধানটি পেয়েছি, এটি বেশ সহজ এবং সোজা এগিয়ে, এই আলোচনাটি ব্যবহার করে , আমি ভেবেছিলাম যে ডাব্লুএমআইসি কমান্ডটি চালানো এত সহজ হবে be এবং সেই মানটি পান, এখানে সি # কোড। আপনার কেবলমাত্র সিস্টেম.ম্যানেজমেন্ট নেমস্পেস (এবং প্রক্রিয়াটির জন্য আরও কয়েকটি স্ট্যান্ডার্ড নেমস্পেস) ব্যবহার করতে হবে।

string fileName = Path.Combine(Environment.SystemDirectory, "wbem", "wmic.exe");
string arguments = @"cpu get NumberOfCores";

Process process = new Process
{
    StartInfo =
    {
        FileName = fileName,
        Arguments = arguments,
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true
    }
};

process.Start();

StreamReader output = process.StandardOutput;
Console.WriteLine(output.ReadToEnd());


process.WaitForExit();
int exitCode = process.ExitCode;
process.Close();

4
আপনি কেন সাধারণ ডাব্লুএমআই ক্যোয়ারী এত জটিল করেন তা নিশ্চিত নন। ডাব্লুএমআই কমান্ড-লাইনটিকে একটি বাহ্যিক প্রক্রিয়া হিসাবে শুরু করা এবং এর আউটপুটকে বিশ্লেষণ করা সত্যিই প্রয়োজনীয় নয়। .NET এর ডাব্লুএমআই ক্যোরিয়াসগুলির জন্য অন্তর্নির্মিত সমর্থন রয়েছে (সিস্টেম.ম্যানেজমেন্ট.ম্যানেজমেন্টঅবজেক্টসিয়ারচার), এখানে অন্যান্য উত্তরগুলির কয়েকটি ইতিমধ্যে চিত্রিত হিসাবে। এছাড়াও, আমি জানি না আপনি কেন ভাবেন যে নট প্যাকেজ বা সার্ভিস প্যাকগুলি প্রয়োজন হবে যখন ডাব্লু.এম.ইক্সির পরিবর্তে .NET এর বিল্ট-ইন ডাব্লুএমআই সমর্থন ...
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.