What is the C way to report progress of computation? [closed] - c

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 6 years ago.
Improve this question
This is a follow-up question to Using a thread in C++ to report progress of computations.
Suppose that I have a for loop which executes run_difficult_task() many times, and I would like to infer how far the loop has advanced. I used to write:
int i;
for (i=0; i < 10000; ++i) {
run_difficult_task(i);
if (i % 100 == 0) {
printf("i = %d\n", i);
}
}
but the main problem with such approach is that executing run_difficult_task() might literally take forever (by being stuck in an infinite loop, etc.), so I would like to get a progress report in every k seconds by means of printing out the value of the loop variable i.
I found quite a rich literature on this site regarding object-oriented multithreading (of which I am not really familiar with) in various programming languages, but the questions I found doing this in C-style seem quite outdated. Is there a platform-independent, C11 way to do what I want? If there is not any, then I would be interested in methods working in unix and with gcc.
Note: I do not wish to run various instances of run_difficult_task in parallel (with, for example, OpenMP), but I want to run the for loop and the reporting mechanism in parallel.
Related: How to "multithread" C code and How do I start threads in plain C?

Linux (and also POSIX systems) provide the alarm library call. This allows you to do something after an interval of seconds without interrupting your main thread, and without bothering with multi-threading when you don't really need it. It was very much created for use cases like yours.

You can try using one thread (the worker thread) or possibly two (one that does computations and one that displays output while main is doing something else or just waiting) and some global variables (ugh).
The first thread will be your workhorse doing computations and updating some global variable. The second one (maybe simply the main thread) will then check whether this variable has changed or not and then print the stats (perhaps, that variable will hold the stats, for example, percentage).
What you can try:
int ping = 0, working = 0, data;
// in main thread
for (/* something */){
// spawn worker thread
while (working) {
if (ping) printf("%d\n", data), ping = 0;
}
}
// in worker thread
working = 1;
while (/* something */) {
// do a lot of computations
if (/* some condition */) {
if (! ping) {
data = /* data */
ping = 1;
}
}
}
working = 0;

Here's a simple time based progress indicator that I've often used:
void
progress(int i)
{
time_t tvnow;
static time_t tvlast;
static time_t tvbeg;
if (tvbeg == 0) {
tvbeg = time(NULL);
tvlast = tvbeg - 2;
}
tvnow = time(NULL);
if ((tvnow - tvlast) >= 1) {
printf("\r%ld: i = %d",tvnow - tvbeg,i);
fflush(stdoout);
tvlast = tvnow;
}
}
int i;
for (i=0; i < 10000; ++i) {
run_difficult_task(i);
progress(i);
}
UPDATE:
Does this update if run_difficult_task(i) runs for longer than 2seconds?
No, but I've updated the example to put the progress code in a separate function, which is what I normally do in my own code.
You'll have to add calls to the progress function within run_difficult_task to get finer grain progress--this is something I also do in my own code.
But, notice that I added an elapsed time [in seconds] to the progress.
If you didn't care about that, if run_difficult_task takes longer than 2 seconds to run, there is no progress until it returns as you define it because progress is defined by incrementing i which is done by the outer loop.
For my own stuff, the progress function can handle an arbitrary number of progress indicators from an arbitrary number of worker threads.
So, if that would be of interest to you, and [say] run_difficult_task has some inner loop variables like j, k, l, these could be added to the progress. Or, whatever you wish to report on.

Related

Value being reset in while loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am very new to this programming, trying to seta project up on proteus to add, minus and set an alarm through the use of buttons connected to a PIC. Issue is the count is not saving after the while loop and is being reset.
- button1= ADD, button2=MINUS, button 1+2+3 = ALARM
- cant figure out why overall count is being reset to 0
- Any help would be amazing
#include <main.h>
#ZERO_RAM
int a = 0;
int state;
char data = 'y';
short int flags[3];
char uart_rd;
void main()
{
setup_wdt(WDT_1MS); //~1.0 ms reset
port_a_pullups(0xFF); // Defining PORTA as pullup Resistors
printf("program start" nr); //<------keeps resetting value to 0 HERE
while (TRUE) // infinite loop
{
if (!input(PIN_A1)) // add button
{
if (!flags[0])
{
flags[0] = 1;
a++; // add one to overall count
printf("ADDED, Total= %dnr", a); // prints count
}
}
else
{
flags[0] = 0;
}
if (!input(PIN_A2)) // minus button
{
if (!flags[1])
{
flags[1] = 1;
a--; // take away 1 from count
printf("MINUS, Total= %dnr", a); // print count
}
}
else
{
flags[1] = 0;
}
if ((!input(PIN_A1)) && (!input(PIN_A2)) && (!input(PIN_A3))) // all buttons equal alarm
{
printf("ALARM HAS BEEN SETnr"); // if all buttons are held constant alarm
// is printed through Terminal
}
else
{
flags[2] = 0;
output_high(PIN_A0); // led goes high
delay_ms(500); // flashing LED every cycle
output_low(PIN_A0); // led goes low
printf("Overall Count= %dnr", a); // printf overall count
}
}
}
You have the following bugs:
You never initialize flags anywhere. Sure, static storage duration variables are required by the standard to be initialized to zero. But in embedded systems, there is an incredibly common non-standard extension which removes the "zero-out" part from the start up code. When you create a project you often get an option "minimal startup" or "standard C". Therefore, always initialize all your variables manually in run-time before using them. Robust embedded code makes no assumptions about the default values of variables in neither .datanor .bss segments.
You haven't implemented any debouncing. Please check some beginner tutorial about how to read buttons in embedded systems, to avoid problems with the electro-mechanical signal bounce. The signal bounce causes the code flags[0] = 0; to get executed.
Whenever someone presses a button, your condition for increasing the counter remains true for as long as the button is pressed. The microcontroller is fast enough to run that code many thousand times over during the time a slow human keeps the button pressed. Instead, you should only increase the counter when the button goes from inactive to active. Obviously, the code doing this needs to be located after the debouncing.

Not working OpenMP in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I use a function with a multithread process in a while. The code runs fine sometimes but other times just stops. I have identified that the problem is in the multithread process. Im newbie with multithread and OpenMP... if someone have a tip to solve that... I'll be very grateful. xP
void paralelSim(PetriNet *p, Matrix *mconflit, int steps){
Matrix ring;
choicesRing(p, mconflit, &ring);
clock_t t;
t = clock();
while((ring.row!=0) && ((steps>0) || (steps == CONTINUE))){
omp_set_dynamic(0);
omp_set_num_threads(ring.col);
#pragma omp parallel shared(p)
{
firethread(p, ring.m[0][omp_get_thread_num()]);
}
if(steps != CONTINUE){
steps--;
}
choicesRing(p, mconflit, &ring);
}
t= clock() - t;
printf("%f seconds.\n",t,((float)t)/CLOCKS_PER_SEC);
printf("m:\n");
showMatrix(&p->m);
printf("steps: %d\n", p->steps);
}
Too many information are missing on your code snippet to be sure of anything, but I can at least give you some hints of what could go wrong...
You set the number of threads to an arbitrary value that, I assume, can be quite large. But that's not really in OpenMP's philosophy. Indeed, in OpenMP, you don't expect the number of threads to go far beyond the number of cores or hardware threads available on the machine. I'm sure the run time library can handle much more, but I'm also sure the performance penalty can be sever and I even suspect there is a limit to what it can manage.
You repeatedly forbid nested parallelism. I guess doing it once is enough, unless firethread() set it back on.
You time your runs with clock() which is a bad idea, since it times the CPU time of the current threads and all its children and sums it, instead of reporting the wall time. So you'll never see if you have any speed-up, and you'll even experience reports of slow-downs. Use omp_get_wtime() instead.
Your time printing statement is wrong with 2 values packed for only one in the format list.
Here is a tentative re-write of your code, which I can't compile or test, but which I feel more in-line with what one would expect of an OpenMP code. Maybe it will improve / solve your issue.
void paralelSim(PetriNet *p, Matrix *mconflit, int steps){
Matrix ring;
omp_set_dynamic(0);
choicesRing(p, mconflit, &ring);
double t = omp_get_wtime();
while((ring.row!=0) && ((steps>0) || (steps == CONTINUE))){
#pragma omp parallel for
for(int i=0; i<ring.col; ++i)
firethread(p, ring.m[0][i]);
if(steps != CONTINUE){
steps--;
}
choicesRing(p, mconflit, &ring);
}
t = omp_get_wtime() - t;
printf("%f seconds.\n",t);
printf("m:\n");
showMatrix(&p->m);
printf("steps: %d\n", p->steps);
}
Again, I didn't even compile this so there might (likely) be some typos. Moreover, should it work but not give expected performance, you could consider move the omp parallel part outside of the while loop, and use some omp single where needed.
Finally, since I didn't know how many cores you plan to run this on, I didn't explicitly set the number of threads. This will for the moment rely on either your environment's default, or your setting of the OMP_NUM_THREADS environment variable.

How to change the count of a pthread_barrier?

The problem is that we have to implement a kind of "running-contest" using pthreads. After one track we have to wait until all runners/threads are done until this point, so we use a barrier for that.
But now we also have to implement the probability of injuries. So we wrote a function, which sometimes reduces the number of runners, and reinitialize the barrier with a smaller count. Now the problem is that the program is not always terminating. I guess the reason for this is that some of the threads have already been at the barrier, and after reinitializing them the required amount is not arriving.
The code for the simulation of the injury looks like this:
void simulateInjury(int number) {
int totalRunners = 0;
int i = 0;
if (rand() % 10 < 1) {
printf("Runner of Team %i injured!\n", number);
pthread_mutex_lock(&evaluate_teamsize);
standings.teamSize[number]--;
for (i = 0; i < teams; i++) {
totalRunners += standings.teamSize[i];
}
pthread_barrier_destroy(&barrier_track1);
pthread_barrier_destroy(&barrier_track4[number]);
pthread_barrier_init(&barrier_track1, NULL, totalRunners);
pthread_barrier_init(&barrier_track4[number], NULL, standings.teamSize[number]);
pthread_mutex_unlock(&evaluate_teamsize);
pthread_exit(NULL);
}
}
Or is there maybe a way to just change the count argument of the barrier?
I see two errors:
You should not re-initialize a barrier while some thread is using
it.
You should not execute the re-initialization of the barrier
simultaneously by several threads.
For the first you can create a second barrier that you use in alternation with the first.
For the second you should use the return value of the wait function to designate one particular thread that will do the re-initialization.

Using hardware timer in C

Okay, so I've got some C code to perform a mathematical operation which could, pretty much, take any length of time (depending on the operands supplied to it, of course). I was wondering if there is a way to register some kind of method which will be called every n seconds which can analyse the state of the operation, i.e. what iteration it is currently at, possibly using a hardware timer interrupt or something?
The reason I ask this is because I know the common way to implement this is to be keeping track of the current iteration in a variable; say, an integer called progress and have an IF statement like this in the code:
if ((progress % 10000) == 0)
printf("Currently at iteration %d\n", progress);
but I believe that a mod operation takes a relatively long time to execute, so the idea of having it inside a loop which will be ran many, many times scares me, from an optimisation point of view.
So I get the feeling that having an external way of signalling a progress print is nice and efficient. Are there any great ways to perform this, or is the simple 'mod check' the best (in terms of optimising)?
I'd go with the mod check, but maybe with subtractions instead :-)
icount = 0;
progress = 10000;
/* ... */
if (--progress == 0) {
progress = 10000;
printf("Currently at iteration %d0000\n", ++icount);
}
/* ... */
While mod operations are usually slow, the compiler should be able to optimize and predict this really well and only mis-predict once ever 10'000 ifs, burning one mod operation and ~20 cycles (for the mis-prediction) on it, which is fine. So you are trying to optimize one mod operation every 10'000 iterations. Of course this assumes you are running it on a modern and typical CPU, and not some embedded system with unknown specs. This should even be faster than having a counter variable.
Suggestion: Test it with and without the timing code, and figure out a complex solution if there is really a problem.
Premature optimisation is the root of all evil. -Knuth
mod is about the same speed as division, on most CPU's these days that means about 5-10 cycles... in other words hardly anything, slower than multiply/add/subtract, but not enough to really worry about.
However you are right to want to avoid sting in a loop spinning if you're doing work in another thread or something like that, if you're on a unixish system there's timer_create() or on linux the much easier to use timerfd_create()
But for single threaded, just putting that if in is enough.
Use alarm setitimer to raise SIGALRM signals at regular intervals.
struct itimerval interval;
void handler( int x ) {
write( STDOUT_FILENO, ".", 1 ); /* Defined in POSIX, not in C */
}
int main() {
signal( SIGALRM, &handler );
interval.it_value.tv_sec = 5; /* display after 5 seconds */
interval.it_interval.tv_sec = 5; /* then display every 5 seconds */
setitimer( ITIMER_REAL, &interval, NULL );
/* do computations */
interval.it_interval.tv_sec = 0; /* don't display progress any more */
setitimer( ITIMER_REAL, &interval, NULL );
printf( "\n" ); /* done with the dots! */
}
Note, only a smattering of functions are OK to call inside handler. They are listed partway down this page. If you want to communicate anything for a fancier printout, do it through a sig_atomic_t variable.
you could have a global variable for the iterations, which you could monitor from an external thread.
While () {
Print(iteration);
Sleep(1000);
}
You may need to watch out for data races though.

Is this a good implementation of a FPS independant game loop?

I currently have something close to the following implementation of a FPS independent game loop for physics based games. It works very well on just about every computer I have tested it on, keeping the game speed consistent when frame rate drops. However I am going to be porting to embedded devices which will likely struggle harder with video and I am wondering if it will still cut the mustard.
edits:
For this question assume that msecs() returns the time passed in milliseconds which the program has run. The implementation of msecs is different on different platforms. This loop is also run in different ways on different platforms.
#define MSECS_PER_STEP 20
int stepCount, stepSize; // these are not globals in the real source
void loop() {
int i,j;
int iterations =0;
static int accumulator; // the accumulator holds extra msecs
static int lastMsec;
int deltatime = msec() - lastMsec;
lastMsec = msec();
// deltatime should be the time since the last call to loop
if (deltatime != 0) {
// iterations determines the number of steps which are needed
iterations = deltatime/MSECS_PER_STEP;
// save any left over millisecs in the accumulator
accumulator += deltatime%MSECS_PER_STEP;
}
// when the accumulator has gained enough msecs for a step...
while (accumulator >= MSECS_PER_STEP) {
iterations++;
accumulator -= MSECS_PER_STEP;
}
handleInput(); // gathers user input from an event queue
for (j=0; j<iterations; j++) {
// here step count is a way of taking a more granular step
// without effecting the overall speed of the simulation (step size)
for (i=0; i<stepCount; i++) {
doStep(stepSize/(float) stepCount); // forwards the sim
}
}
}
I just have a few comments. The first is that you don't have enough comments. There are places where it's not clear what you are trying to do so it is difficult to say if there is a better way to do it, but I'll point those out as I come to them. First, though:
#define MSECS_PER_STEP 20
int stepCount, stepSize; // these are not globals in the real source
void loop() {
int i,j;
int iterations =0;
static int accumulator; // the accumulator holds extra msecs
static int lastMsec;
These are not initialized to anything. The probably turn up as 0, but you should have initialized them. Also, rather than declaring them as static you might want to consider putting them in a structure that you pass into loop by reference.
int deltatime = msec() - lastMsec;
Since lastMsec wasn't (initialized and is probably 0) this probably starts out as a big delta.
lastMsec = msec();
This line, just like the last line, calls msec. This is probably meant as "the current time", and these calls are close enough that the returned value is probably the same for both calls, which is probably also what you expected, but still, you call the function twice. You should change these lines to int now = msec(); int deltatime = now - lastMsec; lastMsec = now; to avoid calling this function twice. Current time getting functions often have much higher overhead than you think.
if (deltatime != 0) {
iterations = deltatime/MSECS_PER_STEP;
accumulator += deltatime%MSECS_PER_STEP;
}
You should have a comment here that says what this does, as well as a comment above
that says what the variables were meant to mean.
while (accumulator >= MSECS_PER_STEP) {
iterations++;
accumulator -= MSECS_PER_STEP;
}
This loop needs a comment. It also needs to not be there. It appears that it could have been replaced with iterations += accumulator/MSECS_PER_STEP; accumulator %= MSECS_PER_STEP;. The division and modulus should run in shorter and more consistent time than the loop on any machine that has hardware division (which many do).
handleInput(); // gathers user input from an event queue
for (j=0; j<iterations; j++) {
for (i=0; i<stepCount; i++) {
doStep(stepSize/(float) stepCount); // forwards the sim
}
}
Doing steps in a loop independent of input will have the effect of making the game unresponsive if it does execute slow and get behind. It appears, at least, that if the game gets behind all of the input will start to stack up and get executed together and all of the in-game time will pass in one chunk. This is a less than graceful way to fail.
Additionally, I can guess what the j loop (outer loop) means, but the inner loop I am less clear on. also, the value passed to the doStep function -- what does that mean.
}
This is the last curly brace. I think that it looks lonely.
I don't know what goes on as far as whatever calls your loop function, which may be out of your control, and that may dictate what this function does and how it looks, but if not I hope that you will reconsider the structure. I believe that a better way to do it would be to have a function that is called repeatedly but with only one event at the time (issued regularly at a relatively short period). These events can be either user input events or timer events. User input events just set things up to react upon the next timer event. (when you don't have any events to process you sleep)
You should always assume that each timer event is processed at the same period, even though there may be some drift here if the processing gets behind. The main oddity that you may notice here is that if the game gets behind on processing timer events and then catches up again the time within the game may appear to slow down (below real time), then speed up (to real time), and then slow back down (to real time).
Ways to deal with this include only allowing one timer event to be in the event queue at one time, which would result in time appearing to slow down (below real time) and then speed back up (to real time) with no super speed interval.
Another way to do this, which is functionally similar to what you have, would be to have the last step of processing each timer event be to queue up the next timer event (note that no one else should send timer events {except for the first one} if this is the way you choose to implement the game). This would mean doing away with the regular time intervals between timer events and also restrict the ability for the program to sleep, since at the very least every time the event queue were inspected there would be a timer event to process.

Resources