Search code examples
cstatuspresentation

Show running status in percentage during computing


I am currently writing a command line C program. There are tons of complex loops and computing in my program. Here comes a problem that my program consumes about 2 minutes to finish computing so I'd like to print something during computing in order to show it is running well, otherwise the programme will run in silence for 2 minutes which seems to be too long for users and they may think it crashes.

However if I simply insert a line of code to print certain values into the main loop, it will slow down my program significantly (I guess it's because my code will wait until the printf function has effect on the screen).

Now I have a functional but really ugly solution i.e. print once every 1000 loops. For me, ideally the best solution for this problem is printing status in percentage and simutanously running the code in the background. (Just like execute sudo apt-get update in Linux)


Solution

  • A simple single threaded solution would be to check every x (e.g. 1000) loop iterations wether your desired next status milestone (e.g. 1%) has been reached and print out a statement then. Optionally check wether at least (half) a second has passed.

    #include <sys/time.h>
    
    struct timeval last, now;
    gettimeofday(&last, NULL);
    size_t lastprint = 0;
    
    size_t i;
    for (i = 0; i < num_iterations; i++) {
        if (!(i & 0x3FF)) { // every 1024 iterations
            if ( 100 * (i - lastprint) / num_iterations >= 1) { // at least one percent passed
                gettimeofday(&now, NULL);
    
                if (now.tv_usec - last.tv_usec + (1000000 * (now.tv_sec - last.tv_sec)) > 500000) { // at least half a second passed
                    // print status
    
                    last = now;
                    lastprint = i;
    
                }
            }
        }
    
        // do work
    }
    

    Depending on how long a loop iteration takes it may or may not have performance impacts. As a rule of thumb: if your loop takes longer then 20 nanoseconds to execute you will be fine with this.

    If your loops are that small that you can't afford to have an extra branch in them for status messages then

    • You should consider parallelising your code first
    • You should put the iteration index into a shared variable and check it with a status printing thread every (half a) second and print status messages like this.