Solved

Determine physical CPU count for a computer using C#

Posted on 2006-11-25
18
6,796 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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!

 
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
 
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

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

726 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