• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7069
  • Last Modified:

Determine physical CPU count for a computer using C#

I am writing a simple asset management application to collect information about remote computers and store the information in a database for reporting. I am mostly using WMI to collect the information.

The issue I am having is that no matter how I try to collect the CPU count, I get back incorrect information. Because of the introduction of Hyperthreading and Dual Core CPUs, the CPU counts show double or even quadruple CPU counts. For example, if a computer has 2 physical CPUs and have hyperthreading enabled, the CPU count will show as 4 CPUs. If the same computer is using Dual Core CPUs with Hyperthreading enabled, the CPU count will be 8. This is the number shown anywhere you look in the operating system is also skewed by dual core and hyperthreaded CPUs.

Does anyone have any idea of a way I can determine the real physical CPU count?

Thanks in adavance!
0
jmiller47
Asked:
jmiller47
  • 10
  • 5
  • 2
  • +1
1 Solution
 
jmiller47Author Commented:
It appears that this is a C# client applications that calls a C++ coded compiled DLL. In this case, it would be C++ that is determining the CPU counts. Do you how this might convert to C# or another way?  I would rather not reference any external DLLs and only use the built -in .NET framework.

Thanks!
0
 
NightmanCTOCommented:
I'll be honest, you got me intrigued, so I have been doing some googling since I posted this. This is the best sample I could find that uses C#. The C++ is managed C++, so is native .NET anyway, but I suspect that this is not properly exposed in .NET.

It is also possible that the sample in that article does not accurately count the cores, but I don't have a DC machine with me right now to test it.

If I find more, I will post here.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ostdpCommented:
You can use

            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();

to get the WMI information on the processors.


Have a look in the System.Management documnetation.
0
 
jmiller47Author Commented:
Thanks ostdp,
However, that returns the logical, not the physical processor count. I am very familiar on the WMI object model, however, it appears that you cannot return the physical count, only the logical count. If there is a way to convert that C++ code to C#, that would defnitely suffice.

Thanks
0
 
Expert1701Commented:
> If the same computer is using Dual Core CPUs with Hyperthreading enabled, the CPU count will be 8.

  I don't believe this is true.  I am running a single Dual-Core processor with Hyperthreading and the CPU count is only 2 (not 4).

> If there is a way to convert that C++ code to C#, that would defnitely suffice.

  No, because it uses assembly.  You can easily use the C++ DLL in your application as demonstrated by the Code Project article.

Having said that, here is a pure C# solution that should work:

(modified from) Detect Hyperthreading in C# using WMI
http://www.xmilk.com/Home/tabid/36/EntryID/11/Default.aspx

  using System;
  using System.Collections;
  using System.Management;
  using System.Runtime.InteropServices;

  class Program
  {
    static void Main()
    {
      Console.WriteLine("Logical CPUs:  " + Environment.ProcessorCount);
      Console.WriteLine("Physical CPUs: " + PhysicalProcessorCount());
      Console.ReadLine();
    }

    static int PhysicalProcessorCount()
    {
      ArrayList processors = new ArrayList();

      foreach (ManagementObject mo in new ManagementClass("Win32_Processor").GetInstances())
      {
        string id = (string)mo.Properties["ProcessorId"].Value;

        if (!processors.Contains(id))
          processors.Add(id);
      }

      return processors.Count;
    }
  }

Returns the following on my system:

  Logical CPUs:  2
  Physical CPUs: 1
0
 
jmiller47Author Commented:
Expert1701 ,
It appears that this code only reads the ProcessorID using WMI and counts all the unique instances. However, on a PowerEdge 6650, Xeon, Quad Proc server, this only returned 1 processor. When looking over the Processor ID in WMI (Win32_Processor), I can find 8 instances of processors, all of them have the same ProcessorID. This is why when I ran the utility, it only returned 1 processor.
0
 
jmiller47Author Commented:
It also appears that if I were to use the C++ compiled dll, I would not be able to check the CPU count remotely, as it does not have an interface for that. I need to be able to connect to hundreds of servers and remotely determine the physical CPU count.

I hope that helps.

Thanks!
0
 
Expert1701Commented:
Can you examine the other properties for something that is unique?
0
 
jmiller47Author Commented:
That is the problem. I have looked at all of the Win32_Processor WMI properties and not found anything that is unique to physical processors. I am looking for any other possibilities.

Thanks!
0
 
Expert1701Commented:
What operating system is that PowerEdge 6650 running?
0
 
jmiller47Author Commented:
Windows 2003 SP1
0
 
jmiller47Author Commented:
OK, Thanks everyone. I finally got this working. In the spirit of sharing, this is what I have. So far, it appears to work. I will be running a test tonight against all servers and comparing that data with the purchase orders (they are on paper and they specify the real processor count, I wanted something automated though...)

I found that the SocketDesignation property from the Win32_Processor class has which physical socket the CPU is located in. If there are more than one logical CPUs using a single socket, I can ignore that duplicate (it is a virtual CPU). I used the same code that Expert1701 provided exchanging ProcessorID with SocketDesignation.

I will keep the Q open until tomorrow until I can verify this works on all servers. If this does work, i will award the points to Expert1702

Thanks everyone!


--------- Begin code snippet here -------------------------------------------------------
using System;
  using System.Collections;
  using System.Management;
  using System.Runtime.InteropServices;

  class Program
  {
    static void Main()
    {
      Console.WriteLine("Logical CPUs:  " + Environment.ProcessorCount);
      Console.WriteLine("Physical CPUs: " + PhysicalProcessorCount());
      Console.ReadLine();
    }

    static int PhysicalProcessorCount()
    {
      ArrayList processors = new ArrayList();

      foreach (ManagementObject mo in new ManagementClass("Win32_Processor").GetInstances())
      {
        string id = (string)mo.Properties["SocketDesignation"].Value;

        if (!processors.Contains(id))
          processors.Add(id);
      }

      return processors.Count;
    }
  }
--------- End code snippet here -------------------------------------------------------
0
 
jmiller47Author Commented:
I tested and verified this. this works as planned.

Thank you everyone!
0
 
Expert1701Commented:
Just out of curiosity, what types of values does SocketDesignation have on a multi-processor system?
0
 
jmiller47Author Commented:
Here is a sample:
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_1
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_2
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_3
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_4
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_1
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_1
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_1
-----------------------------------
Win32_Processor instance
-----------------------------------
SocketDesignation: PROC_1
0
 
jmiller47Author Commented:
FYI - That shows 8 logical instances but only 4 unique socket designations. This means that out of the 8 logical processors in the system, they are only using 4 physical sockets. That means that 4 processors are physically installed.
0
 
Expert1701Commented:
Thanks for the great response, jmiller47!
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 10
  • 5
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now