Alex
Alex

Reputation: 77329

C#: Create CPU Usage at Custom Percentage

I'm looking to test system responsiveness etc. on a few machines under certain CPU usage conditions. Unfortunately I can only create ~100% usage (infinite loop) or not enough CPU usage (I'm using C#).

Is there any way, in rough approximation, as other tasks are running on the system as well, to create CPU usage artificially at 20, 30, 40% (and so forth) steps?

I understand that there are differences between systems, obviously, as CPU's vary. It's more about algorithms/ideas on customizable CPU intensive calculations that create enough usage on a current CPU without maxing it out that I can tweak them then in some way to adjust them to create the desired percentage.

Upvotes: 7

Views: 3727

Answers (6)

Theodor Zoulias
Theodor Zoulias

Reputation: 43400

Here is a function that utilizes all available processors/cores to a customizable percent, and can be cancelled at any time by the calling code.

private static CancellationTokenSource StressCPU(int percent)
{
    if (percent < 0 || percent > 100) throw new ArgumentException(nameof(percent));
    var cts = new CancellationTokenSource();
    for (int i = 0; i < Environment.ProcessorCount; i++)
    {
        new Thread(() =>
        {
            var stopwatch = new Stopwatch();
            while (!cts.IsCancellationRequested)
            {
                stopwatch.Restart();
                while (stopwatch.ElapsedMilliseconds < percent) { } // hard work
                Thread.Sleep(100 - percent); // chill out
            }
        }).Start();
    }
    return cts;
}

Usage example:

var cts = StressCPU(50);
Thread.Sleep(15000);
cts.Cancel();

Result:

CPU usage

Upvotes: 1

Colin Gravill
Colin Gravill

Reputation: 4274

You could add a threaded timer that wakes up on an interval and does some work. Then tweak the interval and amount of work until you approximate the load you want.

    private void button1_Click(object sender, EventArgs e)
    {
        m_timer = new Timer(DoWork);
        m_timer.Change(TimeSpan.Zero, TimeSpan.FromMilliseconds(10));
    }

    private static void DoWork(object state)
    {
        long j = 0;
        for (int i = 0; i < 2000000; i++)
        {
            j += 1;
        }
        Console.WriteLine(j);
    }

alt text

With that and tweaking the value of the loop I was able to add 20%, 60% and full load to my system. It will scale for multiple cores using additional threads for more even load.

Upvotes: 4

Bubblewrap
Bubblewrap

Reputation: 7516

This then?

    DateTime lastSleep = DateTime.Now;            
    while (true)
    {
        TimeSpan span = DateTime.Now - lastSleep;
        if (span.TotalMilliseconds > 700)
        {
            Thread.Sleep(300);
            lastSleep = DateTime.Now;
        }
    }

You could use smaller numbers to get a more steady load....as long as the ratio is whatever you want. This does only use one core though, so you might have to do this in multiple threads.

Upvotes: 5

Erik
Erik

Reputation:

When you tried using sleep, did you do like this or just put the sleep inside the actual loop? I think this will work.

while(true)
{
  Thread.Sleep(0);
  for(int i=0;i<veryLargeNumber; i++)
  {
      //maybe add more loops here if looping to veryLargeNumber goes to quickly
      //also maybe add some dummy operation so the compiler doesn't optimize the loop away
  }
}

Upvotes: 0

Preet Sangha
Preet Sangha

Reputation: 65476

Not done this - but you could try working out prioritised threads running in multiple programs.

Upvotes: 0

Related Questions