How do you detect the number of physical processors/cores in .net?
Environment.ProcessorCount
EDIT: available in .NET 2.0, not in .NET 1.1
System.Environment.ProcessorCount
returns the number of logical processors
http://msdn.microsoft.com/en-us/library/system.environment.processorcount.aspx
For physical processor count you'd probably need to use WMI - the following metadata is supported in XP/Win2k3 upwards (Functionality enabled in SP's prior to Vista/Win2k8).
Win32_ComputerSystem.NumberOfProcessors returns physical count
Win32_ComputerSystem.NumberOfLogicalProcessors returns logical (duh!)
Be cautious that HyperThreaded CPUs appear identical to multicore'd CPU's yet the performance characteristics are very different.
To check for HT-enabled CPUs examine each instance of Win32_Processor and compare these two properties.
Win32_Processor.NumberOfLogicalProcessors
Win32_Processor.NumberOfCores
On multicore systems these are typically the same the value.
Environment.ProcessorCount will also include any hyperthreaded processors.
There is no way (at least up through Windows 2003) to distinguish a hyperthreaded processor from one with two cores.
This actually varies quite a bit depending on the target platform. Stephbu's answer will work great on XP SP3 and newer.
If you are targeting older platforms, you may want to check out this article. I wrote it about half a year ago and in it I discuss several different ways to do this as well as the individual pros and cons of each method.
You may also want to check out this code project article if you are interested in differentiating shadow cores from hyperthreading from real ones.
While Environment.ProcessorCount will indeed get you the number of virtual processors in the system, that may not be the number of processors available to your process. I whipped up a quick little static class/property to get exactly that:
// <copyright file="ProcessInfo.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 All Rights Reserved
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-08-05</date>
// <summary>Part of the Aesop.Diagnostics.dll assembly.</summary>
namespace Aesop
{
#region Using Directives
// System namespaces
using System;
using System.Diagnostics;
#endregion
#region Class Definition : ProcessInfo
/// <summary>
/// Privides a single property which gets the number of processor threads
/// available to the currently executing process.
/// </summary>
internal static class ProcessInfo
{
#region Internal Static Properties
/// <summary>
/// Gets the number of processors.
/// </summary>
/// <value>The number of processors.</value>
internal static uint NumberOfProcessorThreads
{
get
{
using (Process currentProcess = Process.GetCurrentProcess())
{
uint result;
if (currentProcess == null)
{
result = (uint)Environment.ProcessorCount;
}
else
{
const uint BitsPerByte = 8;
uint loop = BitsPerByte * sizeof(uint);
uint processAffinityMask =
(uint)currentProcess.ProcessorAffinity;
result = 0;
while (loop > 0)
{
--loop;
result += processAffinityMask & 1;
processAffinityMask >>= 1;
}
}
return (result != 0) ? result : 1;
}
}
}
#endregion
}
#endregion
}
Don't have enough rep for the wiki, but note that in addition to XPSP2, Windows 2003 Server SP1 and SP2 also need a hotfix to enable this functionality: