有没有办法通过。net / c#找到CPU核数?
PS:这是一个直接的代码问题,不是一个“我应该使用多线程吗?”的问题!: -)
有没有办法通过。net / c#找到CPU核数?
PS:这是一个直接的代码问题,不是一个“我应该使用多线程吗?”的问题!: -)
当前回答
环境。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;
}
}
}
}
Environment.ProcessorCount
(文档)
来自。net Framework源代码
你也可以在Kernel32.dll上使用PInvoke来获得它
下面的代码或多或少来自System的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();
最简单的方法=环境。ProcessorCount 例子来自环境。ProcessorCount财产
using System;
class Sample
{
public static void Main()
{
Console.WriteLine("The number of processors " +
"on this computer is {0}.",
Environment.ProcessorCount);
}
}