4

I'm writing a small winforms application that opens several instances of another program. To optimize performance I'm looking for a way to find the least used CPU core to assign the process to.

I'd also like to be able to see the usage % of each core. Nothing fancy, a TextBox or Label is fine.

I've been trying to use PerformanceCounter after coming across these answers:

Finding core number

CPU usage for more than 2 cores

I tried implementing these as follows:

        StatusBarOutput.Text = "";
        //ignoring posible hyper-threading for simplicity's sake
        var coreUsages = new PerformanceCounter[Environment.ProcessorCount];

        for (var i = 0; i < coreUsages.Length; i++)
        {
            coreUsages[i] = new PerformanceCounter("Processor", "% Processor Time", i.ToString());

            //using the status bar as output for now, doesn't really matter
            StatusBarOutput.Text += "   |   " + coreUsages[i].CounterName + " ~ " + coreUsages[i].NextValue();
        }

The output I'm getting is:

output

Meanwhile, the Task manager is showing this:

output

Not sure what I'm missing here.

Community
  • 1
  • 1
Asaf Sitner
  • 599
  • 1
  • 10
  • 18

3 Answers3

7

The OS is likely much better at determining which core to use. The folks at MS have spent a lot of time optimizing this particular aspect.

If you try to take it over, are you going to maintain this for every new service pack, version of OS, hardware flavor, etc?

Your best bet is likely to spend some time optimizing the processes, not trying to outguess the OS.

UPDATE:

With performance counters, it's not quite as simple as just grabbing the first value you find. You need to poll at least twice (with some time in between) to get a value.

This isn't necessarily how I would implement this in a real world scenario, but here is the idea:

var coreUsages = new PerformanceCounter[Environment.ProcessorCount];

for (var i = 0; i < coreUsages.Length; i++)
{
     coreUsages[i] = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
     coreUsages[i].NextValue();
}

Thread.Sleep(1000);

for (var i = 0; i < coreUsages.Length; i++)
{
     //using the status bar as output for now, doesn't really matter
     Trace.WriteLine("   |   " + coreUsages[i].CounterName + " ~ " + coreUsages[i].NextValue());
}
RQDQ
  • 15,461
  • 2
  • 32
  • 59
  • I see the reason in letting the OS decide. However, I'm still getting off results from the `PerformanceCounter`. – Asaf Sitner May 17 '12 at 15:11
  • 2
    I actually find this to be an interesting question. There is no harm in experimenting. If the question was focused on measuring CPU load, I would have answered that. However, the OP was kind enough to describe his or her primary goal so I spoke to that. – RQDQ May 17 '12 at 15:11
  • Nothing, but you should let each one do the tasks he's designed for. Maintaining CPUs with an even load is a work of the SO so it has no sense to try to handle this by yourself. Like you don't access directly the HD and let the SO do its job ... – Ignacio Soler Garcia May 17 '12 at 15:13
  • Said that I completely agree with RQDQ – Ignacio Soler Garcia May 17 '12 at 15:13
  • I am more curious to know why his code is showing `0%` load while *Task Manager* says things are crazy. –  May 17 '12 at 15:14
  • That I'd like to know as well. – Asaf Sitner May 17 '12 at 15:15
  • I added some additional information on the performance counter issue. – RQDQ May 17 '12 at 17:16
  • The mystery is revealed, then. Polling twice with a `Thread.Sleep` in between seems to solve the problem. Thanks for the help everyone! – Asaf Sitner May 17 '12 at 18:57
0

Ah! I may see what it is.

In this line of code:

        coreUsages[i].NextValue();

NextValue() returns a float.

If you are casting 0.35 (or 35%) to an integer, you will get 0.

0

For the purpose of experimenting, I suppose you could use GetCurrentProcess() from the Process class under System.Diagnostics. From the returned process, you can set the ProcessAffinity property to whichever core you've detected has the lowest usage based on your code to calculate usage per core.

As others have mentioned, it's a bad idea to try and do this in a real application.

ravibhagw
  • 1,740
  • 17
  • 28