를 통해 CPU 코어 수를 찾는 방법.NET/C#?
경유하는 방법이 있습니까?NET/C#에서 CPU 코어 수를 확인하시겠습니까?
PS 이것은 "멀티스레딩을 사용해야 하나요?" 질문이 아닌 직선 코드 질문입니다! :-)
프로세서와 관련된 여러 가지 정보를 얻을 수 있습니다.
- 물리적 프로세서 수
- 코어 수
- 논리 프로세서 수입니다.
이중 코어 하이퍼스레딩 지원 프로세서가 2개인 시스템의 경우 물리적 프로세서 2개, 코어 4개, 논리적 프로세서 8개가 있습니다.
논리 프로세서의 수는 환경 클래스를 통해 사용할 수 있지만 다른 정보는 WMI를 통해서만 사용할 수 있습니다(일부 시스템에서 사용하려면 핫픽스 또는 서비스 팩을 설치해야 할 수도 있음).
프로젝트의 참조를 시스템에 추가해야 합니다.Management.dll In.NET Core, NuGet 패키지로 사용할 수 있습니다(Windows 전용).
물리적 프로세서:
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);
OR
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);
}
Windows에서 제외된 프로세서:
또한 setupapi.dll의 Windows API 호출을 사용하여 Windows에서 제외된 프로세서(예: 부팅 설정을 통해)를 검색할 수도 있습니다.아래 코드는 Windows에서 제외된 논리 프로세서를 포함하여 존재하는 논리 프로세서의 총 수를 나타냅니다.
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,
}
Environment.ProcessorCount
WMI 쿼리가 느리므로 선택*을 사용하는 대신 원하는 구성원만 선택하십시오.
다음 쿼리에는 3.4초가 소요됩니다.
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
이 경우 0.122초가 소요됩니다.
foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())
환경.ProcessorCount는 로컬 시스템의 코어 수를 제공해야 합니다.
방법은 = 가쉬운방법장= =Environment.ProcessorCount
환경의 예.프로세서 수 속성
using System;
class Sample
{
public static void Main()
{
Console.WriteLine("The number of processors " +
"on this computer is {0}.",
Environment.ProcessorCount);
}
}
방법을 보는 것은 꽤 흥미롭습니다.NET 내부적으로 최소한...아래와 같이 "단순"합니다.
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;
}
}
}
}
.NET Framework 원본
PINvoke를 켜면 얻을 수도 있습니다.Kernel32.dll
다음 코드는 어느 정도 다음에서 옵니다.SystemInfo.cs
시스템에서.웹 소스 위치:
[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;
}
}
여기에는 이미 많은 답이 있지만, 일부는 찬성표가 많고 틀렸습니다.
.NET 환경.ProcessorCount는 잘못된 값을 반환하며 시스템 WMI가 잘못 구성되면 심각한 실패를 초래할 수 있습니다.
신뢰할 수 있는 방법으로 코어 수를 계산하려면 Win32 API가 유일합니다.
다음은 C++ 스니펫입니다.
#include <Windows.h>
#include <vector>
int num_physical_cores()
{
static int num_cores = []
{
DWORD bytes = 0;
GetLogicalProcessorInformation(nullptr, &bytes);
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> coreInfo(bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
GetLogicalProcessorInformation(coreInfo.data(), &bytes);
int cores = 0;
for (auto& info : coreInfo)
{
if (info.Relationship == RelationProcessorCore)
++cores;
}
return cores > 0 ? cores : 1;
}();
return num_cores;
}
그리고 이거는.NET C# 질문, 다음은 포팅된 버전입니다.
[StructLayout(LayoutKind.Sequential)]
struct CACHE_DESCRIPTOR
{
public byte Level;
public byte Associativity;
public ushort LineSize;
public uint Size;
public uint Type;
}
[StructLayout(LayoutKind.Explicit)]
struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION
{
[FieldOffset(0)] public byte ProcessorCore;
[FieldOffset(0)] public uint NumaNode;
[FieldOffset(0)] public CACHE_DESCRIPTOR Cache;
[FieldOffset(0)] private UInt64 Reserved1;
[FieldOffset(8)] private UInt64 Reserved2;
}
public enum LOGICAL_PROCESSOR_RELATIONSHIP
{
RelationProcessorCore,
RelationNumaNode,
RelationCache,
RelationProcessorPackage,
RelationGroup,
RelationAll = 0xffff
}
struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION
{
public UIntPtr ProcessorMask;
public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
public SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION ProcessorInformation;
}
[DllImport("kernel32.dll")]
static extern unsafe bool GetLogicalProcessorInformation(SYSTEM_LOGICAL_PROCESSOR_INFORMATION* buffer, out int bufferSize);
static unsafe int GetProcessorCoreCount()
{
GetLogicalProcessorInformation(null, out int bufferSize);
int numEntries = bufferSize / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
var coreInfo = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[numEntries];
fixed (SYSTEM_LOGICAL_PROCESSOR_INFORMATION* pCoreInfo = coreInfo)
{
GetLogicalProcessorInformation(pCoreInfo, out bufferSize);
int cores = 0;
for (int i = 0; i < numEntries; ++i)
{
ref SYSTEM_LOGICAL_PROCESSOR_INFORMATION info = ref pCoreInfo[i];
if (info.Relationship == LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore)
++cores;
}
return cores > 0 ? cores : 1;
}
}
public static readonly int NumPhysicalCores = GetProcessorCoreCount();
한 가지 옵션은 레지스트리에서 데이터를 읽는 것입니다.MSDN 주제 기사: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx)
프로세서는 HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\에서 찾을 수 있습니다.중앙 처리 장치
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달러를 투자할 줄 알았어요.
이 클래스를 사용할 수 있습니다.
public static class CpuCores
{
private static int cores = 0;
public static int Number
{
get
{
if (cores > 0) return cores;
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\" +
"{50127dc3-0f36-415e-a6cc-4cb3be910b65}");
if (key == null)
{
cores = Environment.ProcessorCount;
return cores;
}
string[] subkeys = key.GetSubKeyNames();
key.Close();
cores = 0;
if (subkeys != null && subkeys.Length > 0) foreach (string s in subkeys)
{
if (s.Length != 4) continue;
int n;
if (int.TryParse(s, out n) && ++n > cores) cores = n;
}
if (cores <= 0) cores = Environment.ProcessorCount;
return cores;
}
}
}
저는 같은 것을 찾고 있었지만 어떤 nugget이나 서비스 팩도 설치하고 싶지 않아서 이 솔루션을 찾았습니다. 이 토론을 통해 WMIC 명령을 실행하고 그 값을 얻는 것이 매우 쉬울 것이라고 생각했습니다. 여기 C# 코드가 있습니다.시스템만 사용하면 됩니다.관리 네임스페이스(및 프로세스 등을 위한 추가 표준 네임스페이스).
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();
언급URL : https://stackoverflow.com/questions/1542213/how-to-find-the-number-of-cpu-cores-via-net-c
'programing' 카테고리의 다른 글
AWS-lambda, Azure 함수 및 Google Cloud 함수 비교 (0) | 2023.05.16 |
---|---|
VB의 숨겨진 특징.NET? (0) | 2023.05.16 |
gitbash 명령줄 완료를 구성하는 방법은 무엇입니까? (0) | 2023.05.16 |
종합적으로 단일 결과를 얻는 것이 가능합니까? (0) | 2023.05.16 |
기본 64 인코딩 이미지를 디스크에 저장하려면 어떻게 해야 합니까? (0) | 2023.05.16 |