Introduction

I had a code that consists of a thread that was heavily CPU intensive. And I needed to limit its execution so that its CPU usage would not go above a particular limit, irrespective of the hardware/processor over which the program was running.

Moreover we often come across a problem, in which we need to Sleep() a thread for a particular duration of time. Such kind of code often consists of a loop, doing some kind of processing/repetitive polling and sleeping at the end of loop for some time, to save CPU cycles. This goes on and on until the loop is terminated. For example, consider a screen capturing program, which continuously grabs the Desktop Image using BitBlt and send the screen shots to some network socket or queue. In such a program, a thread is dedicated to the task of grabbing the screen and sending it in a loop. Now BitBlt is a very CPU intensive operation, while putting data in a queue is a light weight operation. So this thread would spend most of its time in Bitblt and this will continuously keeps the CPU busy, making other processes starve for CPU.

The Sleep() solution might be ok, but is not the right one, as with Sleep() we cannot control the bandwidth of processing power allocated to that thread. So on high end CPUs, these threads would get very less processing cycles as most of the useful CPU cycles would get wasted while sleeping and on slower processors, these CPU hungry threads would leave little for other processes.

Here is a class that will limit CPU usage of a thread to a specified limit and also help to control its execution. It can be said that it is a better alternative to Sleep().

Using the Code

The core logic of this code is as follows.

The main purpose of our code is to keep the average CPU usage of a thread to a specified limit. This limit is a percentage of sum of user and kernel time spent by the thread to that of sum of idle, user and kernel time spent by the system.

So let's say at time t1 CPU usage by thread is To and by system is Soand let's say at time t2 CPU usage by thread is Tn and by system is Snand let's say the ratio/percentage specified is R.

So if this equation is greater then zero, then we can say that the limit is crossed.Moreover let's say we need to sleep for Z time period, so that the average CPU usage percentage falls below the specified limit. So:

This shows how we are going to calculate the time period we need to sleep to keep processor usage within limits.

The core class here is CPULimiter. Most of the code is self explanatory. The main function of this class doing all the above given calculations and making the thread sleep is CalculateAndSleep().

To fetch Thread and System CPU usage timing GetThreadTimes and GetSystemTimes Win32 APIs are being used respectively.

Here is the structure of CPULimiter class:

constint DEFAULT_MAX_PERCENTAGE = 20;
/*
CPULimiter:
This class helps to limit the CPU usage/consumption by a thread involving
some kind of repetitive/polling kind of operation in a loop.
The limit can be set by a user through a function of this class.
*/class CPULimiter
{
//This integer stores last total system time.
//total system time is sum of time spent by system
//in kernel, user and idle mode
LARGE_INTEGER m_lastTotalSystemTime;
//This integer stores last total time spent by this
//thread in kernel space and user space
LARGE_INTEGER m_lastThreadUsageTime;
//Variable used to store maximum thread CPU percentage
//relative to system total time.
int m_ratio;
public:
//Constructors
CPULimiter();
//Constructor with maximum thread cpu usage percentage
CPULimiter(int p_ratio);
//****************Main function.******************
//It evaluates CPU consumption by this thread since
//last call to this function, until now.
//Internally, it calculates if the thread has exceeded
//the maximum CPU usage percentage specified.
//if yes, it makes the thread sleep for a calculated
//time period, to average the total usage to the limit specified.
//Returns TRUE Successful, else FALSE
BOOL CalculateAndSleep();
//Inline setter function
inlinevoid SetRatio(int p_ratio){m_ratio = p_ratio;}
};

//Check if this is first time this function is called
//if yes, escape rest after copying current system and thread time
//for further use
//Also check if the maxCPU of differences between current and previous times
//exceeds the specified maxCPU.
if (thisthreadtime.QuadPart != 0 && (((thisthreadtime.QuadPart - m_lastThreadUsageTime.QuadPart) * 100) - ((thissystime.QuadPart - m_lastTotalSystemTime.QuadPart) * m_maxCPU)) > 0)
{
//Calculate the time interval to sleep for averaging the extra CPU usage
//by this thread.

You actually took the time to write so much crap. Wow...dont you have a life? While you are writting all this crap, your wife is sleeping with your sister. And your sister is blowing your father. I can not come to your place, you live in Punjab, i live in NYC.

I don't know what you mean by these words "Pan shode" and "Ma shod", but what appears from your language these words doesn't have good meanings attached to them.
If no then explain there meaning to me (i only knew these are Irani words as i found in Google).
If yes then i would simply say:

YOU IMMEDIATELY NEED PSYCHIATRIC HELP

Because i see no reason you saying all these to me, this is a technical forum, and i don't even know a single bit about you as a person (before this incidence, but now i have came to know a little bit about your psychic nature from your these repeated messages). So to me it appears you must have some serious problem with your mind and a insane has got access to internet.

And if you knew me somehow and are serious about something then lets discuss it offline, mail me your issue at agarwal.himanshu502@gmail.com or come to my place, I'll assure you, you won't have any issue left after you meet me.

In your intro you say.
"The Sleep() solution might be ok, but is not the right one, as with Sleep() we can not control the bandwidth of processing power allocated to that thread."
then you go ahead and use Sleep() to solve your problem.

This soloution may OK for a few threads but:

1. What about letting the OS do something using thread priorities?
2. When the calculated Sleep() is less than 1ms you are still in a polling loop.
3. You make no mention of the granularity of Sleep() in relation to timer ticks.

Thread priorities gives you a very limited control over how much CPU cycles a particular thread gets in a time frame. And then you don't have fine control over priorities too as there are only definite priority levels and not custom ones. Moreover with thread priorities you just tell the os the importance of a particular thread to execute. But even then a thread is CPU hungry, you will notice, even after assigning it the lowest priority, it consumes almost all the CPU. (And i don't have any answer for this, practically this shouldn't happen).

When the calculated Sleep() is less than 1ms you are still in a polling loop.

This case is handled specially in the code. It might be the case that the calculated time period to Sleep() comes out to be lesser then a millisecond. In this case previous values are not modified so that this particular time chunk comes into account in next calculation, to avoid slippage.

You make no mention of the granularity of Sleep() in relation to timer ticks.

This is something i never notice before and i miss to take care in this code. Thanks you I'll update the code with respect to this information soon.

"Moreover with thread priorities you just tell the os the importance of a particular thread to execute. But even then a thread is CPU hungry, you will notice, even after assigning it the lowest priority, it consumes almost all the CPU. (And i don't have any answer for this, practically this shouldn't happen)."

Of COURSE it should! Thread priorities are just that: PRIORITIES. They rank threads' importances RELATIVE TO EACH OTHER. If only one thread actually wants the CPU at a time, it doesn't matter how unimportant it is, it should get 100% of the time. That's the point of thread priorities. They only matter if two threads are asking for the CPU simultaneously, in which case the more important thread gets more time.

What you have done in your code is throttling, which is quite different to prioritization (and is useful in its own way).

At the CPU level, throttling makes a lot of sense for reducing power consumption and heat output, especially with older CPUs that don't have runtime-changeable clocks. In fact I once kept a CPU working without a fan for a while by force-throttling it to a really low percentage; this was in Linux.

Throttling at the thread level sort of makes sense for similar reasons; for example, you might want to forcefully throttle a thread doing something like SETI-at-home or protein folding so your CPU isn't running at 100% all the time when the system is idle, but allow any other applications you specifically want to use to use as much CPU as they can.

I fully agree that attempting to outguess the scheduler on a matter of correctness by sleeping for tactically interesting periods of time is a completely and utterly disgusting idea and I would never do it.

There are two fairly good cases that webpage missed where Sleep() is useful that I can see right now.

One case is when talking to simple hardware that has timing requirements but doesn't provide any interrupt-oriented interface, such as the parallel port. There are really two subcases here; the first is that you absolutely must wait at least a certain period of time between two actions, and the second is that you will poll the hardware to find out when some action is completed, but don't want to use 100% CPU while polling.

Another case is if you are making some sort of continuously-updated user interface that snapshots some kind of data at some kind of frame rate and displays it. While there are probably better solutions in many cases, one solution would be to have a thread of some sort take a snapshot of the data to display and post a window message to deliver the data, then use Sleep() to wait some period of time before taking another snapshot. Again, this is a tradeoff between update rate and CPU usage, and in many applications using 100% CPU isn't acceptable even if it does lead to the best possible update rate.

Admittedly, only the first subcase of the first case is really a call for Sleep() as such; the other cases would be better framed as a desire for thread throttling, which unfortunately doesn't exist in the Win32 API AFAIK so we have to emulate it.

Thread priorities gives you a very limited control over how much CPU cycles a particular thread gets in a time frame.

"Limited" is absolutely the right word! Window's thread prioritisation is a total POS - in my experience, a difference in thread priority of only 1 and you will be lucky to get an execution ratio of 10:1.

Lone Developer wrote:

You make no mention of the granularity of Sleep() in relation to timer ticks.
This is something i never notice before and i miss to take care in this code.

Consider the MSDN documentation on Sleep[^] (bold added by me):
This function causes a thread to relinquish the remainder of its time slice and become unrunnable for at least the specified number of milliseconds, after which the thread is ready to run.

For legacy reasons the Sleep(...) timer resolution is 55ms so calling Sleep(1) at the moment a thread is resumed will actually yield for 55ms not 1 as is the intent.

Even worse, Sleep(0) does not yield to threads of lower priority! The newer API function SwitchToThread[^] does but it does not include any timing mechanism.