Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I just wrote a simple code to display time in hh:mm:ss format. The code is
#include <stdio.h>
#include <time.h>
int main()
{
time_t curtime;
int h, m, s, ps;
struct tm *x = localtime(&curtime);
time(&curtime);
ps = (*x).tm_sec;
while(1)
{
time(&curtime);
x = localtime(&curtime);
h = (*x).tm_hour;
m = (*x).tm_min;
s = (*x).tm_sec;
if(s != ps)
{
ps = s;
printf("%02d:%02d:%02d\n", h, m, s);
}
}
return(0);
}
The code compiles and runs as expected. However the cpu usage seems to go really high. When I use 'top' to see cpu usage, it shows cpu% as 96-100% (and I can hear the computer fan loud). How can I improve the code from a performance angle keeping the code simple and short?
The reason is that your loop hardly contain anything to be waited on (the only thing is the printfs, but I assume that you redirect that or that printf for some other reason completes quickly). This means that the program always is eligible to run.
All other programs that run on your computer on the other hand often wait for something: user input, network messages or whatever. That means that they are not eligible to run most of the time.
What the operating system does then is because your program has work to do, but no other process has (currently) it will schedule your program to run most of the time (96-100%). Consequently it will consume that much CPU.
This is normally not a bad thing. If your program has work to do it should be given the opportunity to do so if it's the only program that has. It's not really about performance - or put in another way, it's about performance it is that the OS will give your program the opportunity to finish as fast as possible (although it has no idea that it will not finish at all in this case).
One thing one often does with these kind of processes (ie those that are CPU bound) is to lower their priority. This may seem counterintuitive at first, but in effect it will tell the OS to assign to that process all processing power that's not used for anything else, it would mean that there will be processing power available whenever some other program has to process a mouse click, or keyboard input (which means that you wouldn't notice that much that there's a CPU heavy computation going on). Some OSes tries to do this automatically (Linux for example will give precedence to processes that wait a lot).
Generally speaking, since you have an infinite loop, your program will use all processor power to execute itself as fast as possible. Most simple c programs terminate within seconds, so this isn't a problem. Yours however, doesn't.
To at least curb the CPU usage heavily, you can leave a sleep() instruction after every iteration of the loop, to give the system time to do other things in between.
Here is an example:
#include <stdio.h>
#include <unistd.h>
int main(void) {
while(1) {
printf("Aha");
sleep(1); // 1s sleep
// Windows:
// ::Sleep(500); // 500ms
}
return 0;
}
Related
So I have this program that continuously check until the condition is true. My problem is whenever I run it, my computer slows down because of the loop. Can anyone please suggest the best and most efficient way to do this? Thank you for your response in advance.
To illustrate my problem, here is a code that represents it:
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <windows.h>
int main(void){
time_t now;
struct tm *local;
while(1){
time(&now);
local = localtime(&now);
if(local->tm_min > 55){
printf("Time:\t%d:%d:%d\n",local->tm_hour,local->tm_min,local->tm_sec);
getch();
exit(0);
}
}
return 0;
}
If polling is really what you want, or you have to use it, then you must give breath to the system by using sleep's.
So, how much to sleep in each iteration? It can be a fixed value (and if you sleep just 1 millisecond you will be stunned at how this is effective). A fixed value, say 20-30 milliseconds is good if you check for slow events like keystrokes by a real user. If, say, you are monitoring a serial port, perhaps you need lower values.
Then, depending on the application, you can also implement a variable sleep time. For example (this is a little stupid but it is just to explain): you wait for keystrokes, and sleep 30 milliseconds. Then you use your program in a pipe and discover that it is painly slow. A solution could be to set the value to sleep equal to 30 ms, but after having read a character, the value is lowered to 0 which causes the sleep to be not performed. Every time the condition fails the value is raised up to the maximum limit (20-30 milliseconds for a keyboard).
-- EDIT AFTER COMMENTS --
It has pointed out that keyboards and serial ports do not need polling, or they should not be polled. Generally speaking this is true, but it depends on the hardware and operating system (which in turn is a piece of software and, if the hardware does not support an interrupt for a given condition, even the OS would have to poll). About keyboards, for example, I thought at those little ones implemented as a matrix of buttons: some small CPUs have special facilities to generate an interrupt on any I/O change, but other don't: in that case polling is the only solution - and it is also ideal for implementing anti-bouncing (this kind of polling is not necessarily performed inside a loop).
For serial ports, it is almost true that nobody would implement one without an interrupt (to avoid polling). But even so, it is difficult to manage the incoming data in an event-driven fashion; often a flag is set, and some other part of the program, which polls that flag, will work out the message.
Event-driven programming seems easy at first, but as soon the program gets bigger the complication augments too.
There are other situations to consider, for example loops which read data from somewhere and process those data. If something else has to be done inside the loop, for example checking how much time is passed, but the reading is blocking, the reading must be implemented in a non-blocking way, and the whole loop must turn into a kind of polling for one or more conditions -unless one uses multi-threading.
Anyway, I agree that polling is evil and should only be used when necessary.
Efficiently? One way or the other you need to put your process to sleep until the condition WILL BE TRUE - then wake up and die (so to speak :-). Since your code includes windows.h I'll assume you're running on Windows and thus have the Sleep() function available.
#include <stdio.h>
#include <windows.h>
#include <time.h>
int main(void)
{
time_t now;
struct tm *local;
DWORD msecs;
time(&now);
local = localtime(&now);
/* (55 * 60000) = msecs in 55 minutes */
msecs = (55 * 60000) - ((local->tm_min * 60000) + (local->tm_sec * 1000));
if(msecs > 0)
Sleep(msecs)
return 0;
}
I'm trying to create simple program that requests a user to input a number but in the upper section I display a clock that updates every second.
Here's what I know
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int a;
int main(void) {
int a =1;
while(a)
{
system("cls");
time_t rawtime;
struct tm* time_;
time(&rawtime);
time_ = localtime(&rawtime);
printf("%i:%i:%i %i %i %i\n", time_->tm_hour, time_->tm_min,
time_->tm_sec, time_->tm_mday, time_->tm_mon+1,
time_->tm_year+1900);
printf("Give the input :");
scanf("%d",&a);
}
return 0;
}
I took the printing time code from Program a simple clock in C
What my code does is print the time and then it waits for the input, but it doesn't update the clock until I give the input.
Is there any possible way to do what I want or what keyword do I needed to search the solution?
I'm sorry if my English broken, but if what I say isn't clear enough just run the code :).
There are only two ways to display something while waiting for input:
use non blocking IO and poll for user input while constantly updating the displayed time. That will be easy with a GUI library or through non portable system calls - sadly non longer standard portable C
use 2 threads, one for updating the display, the other for user input. It is almost portable since C11, except that the support for C threads is optional. And it will lead to a much more complex program
TL/DR: Even if it looks simple (and was indeed possible with basic language in the 80' on any personnal computer), non blocking terminal IO is far from simple in C language because of the assumption that the terminal is just a special case of IO.
Your problem is simple: you can't wait for an user input and do something else meanwhile, unless you use threads. May be what you could do is to wait for an input for a certain amount of time, print time and loop.
Otherwise, just know that using thread is not really complicated, but it will increase significantly the complexity of your program which purpose seemed to remain simple.
What you want is "non-blocking I/O".
How do you do non-blocking console I/O on Linux in C?
There is an answer in the above linked question that has a code snippet. The accepted answer also states that:
you pretty much don't do non-blocking I/O
and if you have to, you will
simplify this another way, by putting the console I/O into a thread or lightweight process.
The code snipped is hideously complicated and in my experience not guaranteed to work.
With the very simple code below, my system (Ubuntu Linux 14.04) simply crashes not even letting my mouse respond. I had to force quit with the power button. I thought Linux is a stable OS tolerable of handling such basic program errors. Did I miss something?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
void check(int isOkay){
if(!isOkay){
printf("error\n");
abort();
}
}
int main(void){
#define n 1000000
int array[n];
sem_t blocker;
int i;
while(1){
if(!fork()){
for(i = 0; i < n; ++i){
array[i] = rand();
}
check(sem_init(&blocker, 0, 0) == 0);
check(sem_wait(&blocker) == 0);
}
}
return 0;
}
Congratulations, you've discovered the fork bomb. There are shell one-liners that can wreak the same sort of havic with a lot less typing on your part.
It is in fact possible to limit the number of processes that a user can spawn using ulimit -- see the bottom of the linked wikipedia articles for details.
A desktop install of Ubuntu is not exactly a hardened server, though. It's designed for usability first and foremost. If you need a locked down system that can't crash, there are better options.
The command ulmit -u shows the maximum number of processes that you can start. However, do not start that many processes in the background: your machine would spend time switching between processes and wouldn't get around to getting actual work done.
The linux does its job of processing your request to create a process, it is for the user to implement his code based on this limit.
The main problem here is determining the best limit. A lot of software doesn't use fork() at all, so do you set the limit to something small like 5? Some software might create a new process whenever it receives a request from network, so do you set the limit to "max. number of network packets"? If you assume most software isn't buggy, then you'd be tempted to set the limit relatively high so that correct software works properly.
The other problem is one of scheduling priorities. In a well designed system things like the GUI would be "high priority" and if it wants CPU time it'd preempt normal/lower priority work immediately. If this was the case, a massive fork bomb running at normal/lower priority would have no effect on the system's ability to respond to the user, and the user would be able to kill the fork bomb without much problem.
Sadly, for a variety of reasons, the scheduler in Linux doesn't work like that. It does support priorities, but to use them you have to be a "real time" process and have to be running as root (which is a massive security disaster). Without sane priorities, Linux assumes that every forked process is as important as everything else, and the CPU/s end up busy doing the forking and there's no CPU time left to respond to the user.
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
// assuming we return times with microsecond resolution
#define STOPWATCH_TICKS_PER_US 1
uint64_t GetStopWatch()
{
LARGE_INTEGER t, freq;
uint64_t val;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&freq);
return (uint64_t) (t.QuadPart / (double) freq.QuadPart * 1000000);
}
void task()
{
printf("hi\n");
}
int main()
{
uint64_t start = GetStopWatch();
task();
uint64_t stop = GetStopWatch();
printf("Elapsed time (microseconds): %lld\n", stop - start);
}
The above contains a query performance counter function Retrieves the current value of the high-resolution performance counter and query performance frequency function Retrieves the frequency of the high-resolution performance counter. If I am calling the task(); function multiple times then the difference between the start and stop time varies but I should get the same time difference for calling the task function multiple times. could anyone help me to identify the mistake in the above code ??
The thing is, Windows is a pre-emptive multi-tasking operating system. What the hell does that mean, you ask?
'Simple' - windows allocates time-slices to each of the running processes in the system. This gives the illusion of dozens or hundreds of processes running in parallel. In reality, you are limited to 2, 4, 8 or perhaps 16 parallel processes in a typical desktop/laptop. An Intel i3 has 2 physical cores, each of which can give the impression of doing two things at once. (But in reality, there's hardware tricks going on that switch the execution between each of the two threads that each core can handle at once) This is in addition to the software context switching that Windows/Linux/MacOSX do.
These time-slices are not guaranteed to be of the same duration each time. You may find the pc does a sync with windows.time to update your clock, you may find that the virus-scanner decides to begin working, or any one of a number of other things. All of these events may occur after your task() function has begun, yet before it ends.
In the DOS days, you'd get very nearly the same result each and every time you timed a single iteration of task(). Though, thanks to TSR programs, you could still find an interrupt was fired and some machine-time stolen during execution.
It is for just these reasons that a more accurate determination of the time a task takes to execute may be calculated by running the task N times, dividing the elapsed time by N to get the time per iteration.
For some functions in the past, I have used values for N as large as 100 million.
EDIT: A short snippet.
LARGE_INTEGER tStart, tEnd;
LARGE_INTEGER tFreq;
double tSecsElapsed;
QueryPerformanceFrequency(&tFreq);
QueryPerformanceCounter(&tStart);
int i, n = 100;
for (i=0; i<n; i++)
{
// Do Something
}
QueryPerformanceCounter(&tEnd);
tSecsElapsed = (tEnd.QuadPart - tStart.QuadPart) / (double)tFreq.QuadPart;
double tMsElapsed = tSecElapsed * 1000;
double tMsPerIteration = tMsElapsed / (double)n;
Code execution time on modern operating systems and processors is very unpredictable. There is no scenario where you can be sure that the elapsed time actually measured the time taken by your code, your program may well have lost the processor to another process while it was executing. The caches used by the processor play a big role, code is always a lot slower when it is executed the first time when the caches do not yet contain the code and data used by the program. The memory bus is very slow compared to the processor.
It gets especially meaningless when you measure a printf() statement. The console window is owned by another process so there's a significant chunk of process interop overhead whose execution time critically depends on the state of that process. You'll suddenly see a huge difference when the console window needs to be scrolled for example. And most of all, there isn't actually anything you can do about making it faster so measuring it is only interesting for curiosity.
Profile only code that you can improve. Take many samples so you can get rid of the outliers. Never pick the lowest measurement, that just creates unrealistic expectations. Don't pick the average either, that is affected to much by the long delays that other processes can incur on your test. The median value is a good choice.
How would be the correct way to prevent a soft lockup/unresponsiveness in a long running while loop in a C program?
(dmesg is reporting a soft lockup)
Pseudo code is like this:
while( worktodo ) {
worktodo = doWork();
}
My code is of course way more complex, and also includes a printf statement which gets executed once a second to report progress, but the problem is, the program ceases to respond to ctrl+c at this point.
Things I've tried which do work (but I want an alternative):
doing printf every loop iteration (don't know why, but the program becomes responsive again that way (???)) - wastes a lot of performance due to unneeded printf calls (each doWork() call does not take very long)
using sleep/usleep/... - also seems like a waste of (processing-)time to me, as the whole program will already be running several hours at full speed
What I'm thinking about is some kind of process_waiting_events() function or the like, and normal signals seem to be working fine as I can use kill on a different shell to stop the program.
Additional background info: I'm using GWAN and my code is running inside the main.c "maintenance script", which seems to be running in the main thread as far as I can tell.
Thank you very much.
P.S.: Yes I did check all other threads I found regarding soft lockups, but they all seem to ask about why soft lockups occur, while I know the why and want to have a way of preventing them.
P.P.S.: Optimizing the program (making it run shorter) is not really a solution, as I'm processing a 29GB bz2 file which extracts to about 400GB xml, at the speed of about 10-40MB per second on a single thread, so even at max speed I would be bound by I/O and still have it running for several hours.
While the posed answer using threads might possibly be an option, it would in reality just shift the problem to a different thread. My solution after all was using
sleep(0)
Also tested sched_yield / pthread_yield, both of which didn't really help. Unfortunately I've been unable to find a good resource which documents sleep(0) in linux, but for windows the documentation states that using a value of 0 lets the thread yield it's remaining part of the current cpu slice.
It turns out that sleep(0) is most probably relying on what is called timer slack in linux - an article about this can be found here: http://lwn.net/Articles/463357/
Another possibility is using nanosleep(&(struct timespec){0}, NULL) which seems to not necessarily rely on timer slack - linux man pages for nanosleep state that if the requested interval is below clock granularity, it will be rounded up to clock granularity, which on linux depends on CLOCK_MONOTONIC according to the man pages. Thus, a value of 0 nanoseconds is perfectly valid and should always work, as clock granularity can never be 0.
Hope this helps someone else as well ;)
Your scenario is not really a soft lock up, it is a process is busy doing something.
How about this pseudo code:
void workerThread()
{
while(workToDo)
{
if(threadSignalled)
break;
workToDo = DoWork()
}
}
void sighandler()
{
signal worker thread to finish
waitForWorkerThreadFinished;
}
void main()
{
InstallSignalHandler;
CreateSemaphore
StartThread;
waitForWorkerThreadFinished;
}
Clearly a timing issue. Using a signalling mechanism should remove the problem.
The use of printf solves the problem because printf accesses the console which is an expensive and time consuming process which in your case gives enough time for the worker to complete its work.