Y a-t-il un moyen via .NET/C# pour connaître le nombre de cœurs du processeur ?
PS : Il s'agit d'une question de code, pas d'une question sur l'utilisation du multithreading ! :-)
Y a-t-il un moyen via .NET/C# pour connaître le nombre de cœurs du processeur ?
PS : Il s'agit d'une question de code, pas d'une question sur l'utilisation du multithreading ! :-)
Il existe plusieurs informations différentes relatives aux processeurs que vous pouvez obtenir :
Tous ces éléments peuvent être différents ; dans le cas d'une machine équipée de 2 processeurs hyperthreading à double cœur, il y a 2 processeurs physiques, 4 cœurs et 8 processeurs logiques.
Le nombre de processeurs logiques est disponible par l'intermédiaire de l'interface utilisateur. Environnement mais les autres informations ne sont disponibles que par le biais de la classe WMI (et vous devrez peut-être installer des hotfixes ou service packs pour l'obtenir sur certains systèmes) :
Assurez-vous d'ajouter une référence à System.Management.dll dans votre projet. Dans .NET Core, il est disponible (pour Windows uniquement) sous la forme d'un paquet NuGet.
Processeurs physiques :
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
Console.WriteLine("Number Of Physical Processors: {0} ", item["NumberOfProcessors"]);
}
Cœurs :
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);
Processeurs logiques :
Console.WriteLine("Number Of Logical Processors: {0}", Environment.ProcessorCount);
OU
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
Console.WriteLine("Number Of Logical Processors: {0}", item["NumberOfLogicalProcessors"]);
}
Processeurs exclus de Windows :
Vous pouvez également utiliser les appels de l'API Windows dans setupapi.dll pour découvrir les processeurs qui ont été exclus de Windows (par exemple par les paramètres de démarrage) et qui ne sont pas détectables par les moyens ci-dessus. Le code ci-dessous donne le nombre total de processeurs logiques (je n'ai pas réussi à trouver comment différencier les processeurs physiques des processeurs logiques) qui existent, y compris ceux qui ont été exclus de 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,
}
@StingyJack : C'est vrai, mais j'aimerais que ce soit dans un format plus agréable. La découvrabilité est assez faible lorsque vous devez construire des requêtes de chaînes brutes.
WMI Code Creator vous aidera à découvrir des valeurs et à créer des requêtes (il peut même générer des stubs en c#/vb.net).
C'est tellement simple et beau que j'en ai presque les larmes aux yeux. Merci pour la réponse !
@KevinKibler D'après la question, je pense que le PO ne comprend pas la différence, et si vous ne connaissez pas la différence, c'est probablement ce que vous voulez.
Les requêtes WMI sont lentes, essayez donc de ne sélectionner que les membres souhaités au lieu d'utiliser Select *.
La requête suivante prend 3.4s :
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
Alors que celui-ci prend 0.122s :
foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())
Sur quel système fonctionnez-vous ? J'utilise plusieurs requêtes "Select *" et cela ne prend pas de temps. partout près de 3,4 secondes, testé sur des milliers d'ordinateurs sur lesquels mon logiciel est déployé. Je fais un Select * parce que j'obtiens plusieurs propriétés de l'objet. Cependant, je le fais un peu différemment : je crée un ObjectQuery sur le Select * ; je récupère le ManagementObjectCollection ; puis foreach ManagementObject dans le ManagementObjectCollection.
Nombre de processeurs de l'environnement devrait vous donner le nombre de cœurs sur la machine locale.
Une option serait de lire les données à partir du registre. Article MSDN sur le sujet : http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.localmachine(v=vs.71).aspx )
Les processeurs, je crois qu'ils peuvent être localisés ici, HKEY_LOCAL_MACHINE \HARDWARE\DESCRIPTION\System\CentralProcessor
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();
}
Je suis raisonnablement sûr que l'entrée dans le registre sera présente sur la plupart des systèmes.
Mais je voudrais ajouter mon grain de sel.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
8 votes
Avez-vous besoin de savoir combien de cœurs il y a ou combien de processeurs logiques il y a ? Pour l'exécution de plusieurs threads, l'un ou l'autre est probablement suffisant, mais il existe des scénarios où la différence peut être importante.
0 votes
Existe-t-il une nouvelle façon de procéder ?