简体   繁体   中英

Extremely CPU Intensive Alarm Clock

EDIT:

I would like to thank you all for the swift replies ^^ Sleep() works as intended and my CPU is not being viciously devoured by this program anymore! I will keep this question as is, but to let everybody know that the CPU problem has been answered expediently and professionally :D

As an aside to the aside, I'll certainly make sure that micro-optimizations are kept to a minimum in the face of larger, more important problems!

================================================================================

For some reason my program, a console alarm clock I made for laughs and practice, is extremely CPU intensive. It consumes about 2mB RAM, which is already quite a bit for such a small program, but it devastates my CPU with over 50% resources at times.

Most of the time my program is doing nothing except counting down the seconds, so I guess this part of my program is the one that's causing so much strain on my CPU, though I don't know why. If it is so, could you please recommend a way of making it less , or perhaps a library to use instead if the problem can't be easily solved?

/* The wait function waits exactly one second before returning to the *
 * called function.                                                   */     
 void wait( const int &seconds )
 {
 clock_t endwait; // Type needed to compare with clock()
 endwait = clock() + ( seconds * CLOCKS_PER_SEC ); 

 while( clock() < endwait ) {} // Nothing need be done here.
 }

In case anybody browses CPlusPlus.com, this is a genuine copy/paste of the clock() function they have written as an example for clock(). Much why the comment //Nothing need be done here is so lackluster. I'm not entirely sure what exactly clock() does yet.

The rest of the program calls two other functions that only activate every sixty seconds, otherwise returning to the caller and counting down another second, so I don't think that's too CPU intensive- though I wouldn't know, this is my first attempt at optimizing code.

The first function is a console clear using system("cls") which, I know, is really, really slow and not a good idea. I will be changing that post-haste, but, since it only activates every 60 seconds and there is a noticeable lag-spike, I know this isn't the problem most of the time.

The second function re-writes the content of the screen with the updated remaining time also only every sixty seconds.

I will edit in the function that calls wait, clearScreen and display if it's clear that this function is not the problem. I already tried to reference most variables so they are not copied, as well as avoid endl as I heard that it's a little slow compared to \\n .

This:

while( clock() < endwait ) {} 

Is not "doing nothing". Certainly nothing is being done inside the while loop, but the test of clock() < endwait is not free. In fact, it is being executed over and over again as fast as your system can possibly handle doing it, which is what is driving up your load (probably 50% because you have a dual core processor, and this is a single-threaded program that can only use one core).

The correct way to do this is just to trash this entire wait function, and instead just use:

sleep(seconds);

Which will actually stop your program from executing for the specified number of seconds, and not consume any processor time while doing so.

Depending on your platform, you will need to include either <unistd.h> (UNIX and Linux) or <windows.h> (Windows) to access this function.

This is called a busy-wait. The CPU is spinning its wheels at full throttle in the while loop. You should replace the while loop with a simple call to sleep or usleep .

I don't know about the 2 MB, especially without knowing anything about the overall program, but that's really not something to stress out over. It could be that the C runtime libraries suck up that much on start-up for efficiency reasons.

The CPU issue has been answered well. As for the memory issue, it's not clear what 2 MB is actually measuring. It might be the total size of all the libraries mapped into your application's address space.

Run and inspect a program that simply contains

int main() { for (;;) }

to gauge the baseline memory usage on your platform.

You're spinning without yielding here, so it's no surprise that you burn CPU cycles.

Drop a

  Sleep(50);

in the while loop.

The while loop is keeping the processor busy whenever your thread gets a timeslice to execute. If all you wish is to wait for a determined amount of time, you don't need a loop. You can replace it by a single call to sleep , usleep or nanosleep (depending on platform and granularity). They suspend the thread execution until the amount of time you specified has elapsed.

Alternatively, you can just give up (yield) on the remaining timeslice, calling Sleep(0) (Windows) or sched_yield() (Unix/Linux/etc).

If you want to understand the exact reason for this problem, read about scheduling .

while( clock() < endwait ) { Sleep(0); } // yield to equal priority threads

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM