Solved

Determine physical CPU count for a computer using C#

Posted on 2006-11-25
18
6,652 Views
Last Modified: 2012-06-22
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
Comment
Question by:jmiller47
  • 10
  • 5
  • 2
  • +1
18 Comments
 
LVL 29

Expert Comment

by:Nightman
ID: 18012233
0
 
LVL 7

Author Comment

by:jmiller47
ID: 18012329
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
 
LVL 29

Expert Comment

by:Nightman
ID: 18012356
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
 
LVL 4

Expert Comment

by:ostdp
ID: 18012869
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
 
LVL 7

Author Comment

by:jmiller47
ID: 18012959
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
 
LVL 11

Accepted Solution

by:
Expert1701 earned 500 total points
ID: 18015528
> 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
 
LVL 7

Author Comment

by:jmiller47
ID: 18021502
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
 
LVL 7

Author Comment

by:jmiller47
ID: 18021541
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
 
LVL 11

Expert Comment

by:Expert1701
ID: 18021760
Can you examine the other properties for something that is unique?
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 7

Author Comment

by:jmiller47
ID: 18021812
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
 
LVL 11

Expert Comment

by:Expert1701
ID: 18021856
What operating system is that PowerEdge 6650 running?
0
 
LVL 7

Author Comment

by:jmiller47
ID: 18021887
Windows 2003 SP1
0
 
LVL 7

Author Comment

by:jmiller47
ID: 18022967
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
 
LVL 7

Author Comment

by:jmiller47
ID: 18023491
I tested and verified this. this works as planned.

Thank you everyone!
0
 
LVL 11

Expert Comment

by:Expert1701
ID: 18023734
Just out of curiosity, what types of values does SocketDesignation have on a multi-processor system?
0
 
LVL 7

Author Comment

by:jmiller47
ID: 18023768
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
 
LVL 7

Author Comment

by:jmiller47
ID: 18023788
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
 
LVL 11

Expert Comment

by:Expert1701
ID: 18023791
Thanks for the great response, jmiller47!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now