Enhanced CPU Stress Tool

June 11, 2016

no comments

The old (but still useful) tool called CPUSTRES (notice the 8-character name) allows simulating CPU activity with up to 4 threads, which can be controlled with activity level and priority. The tool can be downloaded from http://live.sysinternals.com/windowsinternals. Here’s a screenshot:

Old timers may recognize the tool’s icon as the default MFC icon used with Visual C++ 6.

The tool still works, but its age is showing (the binary has been modified in 1999). It has no minimize button, no way to create more threads, no way to change settings for multiple threads at a time, and lacks some other features that may be interesting, such as thread affinity and ideal processor. Part of my work in writing Windows Internals 7th edition is to create experiments involving CPUSTRES and its usage started to annoy me, so…

I’ve decided to create an enhanced version of CPUSTRESS called CPUStressEx (long names are better) that has a more convenient UI and some feature enhancements over the original (I’m on a streak following QSlice):

  • Any number of threads can be created (up to 64)
  • Threads can be terminated
  • Multiple threads can be modified at a time
  • Ideal processor can be set
  • Affinity for threads and the process can be set
  • Thread activity level is indicated by a color
  • Much better UI

Here’s a screenshot of the tool at the time of writing:


At first I thought I’d create the tool with WPF, as building WPF apps is easy and powerful. However, I wanted to minimize the uncontrolled threads in the process. Specifically, with .NET at least one GC thread is created and also a finalizer thread. More threads may be created if various APIs use the .NET thread pool; WPF has a rendering thread as well…

So I decided to create the tool with MFC to help out with the UI. Ideally, no extra threads should be created, although there still might be RPC runtime threads and others that may be the result of window hooks and such. Still, this is the best we can get.

Making the threads busy

The thread activity level is determined with one of 4 levels (Low, Medium, Busy and Maximum), named after the names used in the original tool. When a thread is active, it executes a simple infinite loop shown here:

for (;;) {

    if (::WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0)

        break;

       

    auto level = m_ActivityLevel;

    if (level != ActivityLevel::Maximum) {

        auto time = ::GetTickCount();

        while (::GetTickCount() – time < (unsigned)level * 25)

            ;

        ::Sleep(100 – (int)level * 25);

    }

}

 

First, the thread checks if it needs to break by examining an event created for each thread. Then, the activity level (1 to 4) is used to determine the amount of time to do “work” vs. the amount of time to sleep. An interval of 100 msec is used, part of which is work and part sleep.

If the activity level is set to Maximum, then it’s essentially only work, no sleep. So the loop simply continuously checks the event object. Otherwise, the appropriate percentage is used to do “work” – loop around a certain amount of time and the rest of the 100msec interval is used to sleep.

The source code can be found on GitHub
here.

 

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*