0

Currently I'm polling the register to get the expected value and now I want reduce the CPU usage and increase the performance. So, I think, if we do polling for particular time (Say for 10ms) and if we didn't get expected value then wait for some time (like udelay(10*1000) or usleep(10*1000) delay/sleep in ms) then continue to do polling for more more extra time (Say 100ms) and still if you didn't get the expected value then do sleep/delay for 100ms.....vice versa... need to do till it reach to maximum timeout value.

Please let me know if anything.

This is the old code:

#include <sys/time.h>       /* for setitimer */
#include <unistd.h>     /* for pause */
#include <signal.h>     /* for signal */

#define INTERVAL    500 //timeout in ms
static int timedout = 0;  
struct itimerval it_val;    /* for setting itimer */
char temp_reg[2];

int main(void)
{
  /* Upon SIGALRM, call DoStuff().
   * Set interval timer.  We want frequency in ms, 
   * but the setitimer call needs seconds and useconds. */
  if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR) 
  {
    perror("Unable to catch SIGALRM");
    exit(1);
  }
  it_val.it_value.tv_sec =     INTERVAL/1000;
  it_val.it_value.tv_usec =    (INTERVAL*1000) % 1000000;   
  it_val.it_interval = it_val.it_value;


  if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) 
  {
    perror("error calling setitimer()");
    exit(1);
  }

    do 
    {
        temp_reg[0] = read_reg();
        //Read the register here and copy the value into char array (temp_reg

        if (timedout == 1 )
            return -1;//Timedout

    } while (temp_reg[0] != 0 );//Check the value and if not try to read the register again (poll)



}

/*
 * DoStuff
 */
void DoStuff(void) 
{
  timedout = 1;
  printf("Timer went off.\n");
}

Now I want to optimize and reduce the CPU usage and want to improve the performance.

Can any one help me on this issue ?

Thanks for your help on this.

Titus
  • 43
  • 2
  • 10
  • Maybe you can call `pause()` just before checking `timedout`? It will return just after the signal is processed. – rodrigo Sep 28 '16 at 14:54
  • 1
    Can you use an interrupt instead of polling? – Riley Sep 28 '16 at 14:56
  • Thanks rodrigo, can you please show me some example ? – Titus Sep 28 '16 at 15:01
  • Thanks Riley, can you please show me code ? thanks again – Titus Sep 28 '16 at 15:03
  • To me your question is a bit unclear. Are you asking "how to measure time spend polling" ? In that case see: http://stackoverflow.com/questions/2150291/how-do-i-measure-a-time-interval-in-c – Support Ukraine Sep 28 '16 at 15:13
  • @Titus: Example? Easy: `do { /*...*/ ; pause(); if (timedout == 1) return -1; } while (temp_reg[0] != 0);`. `pause()` is an easy function. It just waits until your process receives a signal. – rodrigo Sep 28 '16 at 15:18
  • Apologize, actually I want to reduce the CPU usage when I do poll method to read the register continuously. I hope you would get idea if you see my code. – Titus Sep 28 '16 at 15:21
  • Thanks rodrigo, yes, I tried it. thanks again. – Titus Sep 28 '16 at 15:38

2 Answers2

1

Currently I'm polling the register to get the expected value [...]

wow wow wow, hold on a moment here, there is a huge story hidden behind this sentence; what is "the register"? what is "the expected value"? What does read_reg() do? are you polling some external hardware? Well then, it all depends on how your hardware behaves.

There are two possibilities:

  1. Your hardware buffers the values that it produces. This means that the hardware will keep each value available until you read it; it will detect when you have read the value, and then it will provide the next value.

  2. Your hardware does not buffer values. This means that values are being made available in real time, for an unknown length of time each, and they are replaced by new values at a rate that only your hardware knows.

If your hardware is buffering, then you do not need to be afraid that some values might be lost, so there is no need to poll at all: just try reading the next value once and only once, and if it is not what you expect, sleep for a while. Each value will be there when you get around to reading it.

If your hardware is not buffering, then there is no strategy of polling and sleeping that will work for you. Your hardware must provide an interrupt, and you must write an interrupt-handling routine that will read every single new value as quickly as possible from the moment that it has been made available.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • Note: I do not know whether your system has any peculiarities, but on most systems, if you decide to sleep, then sleep(1) will generally take you from 100% CPU utilization down to 1% CPU utilization. Is it worth putting any extra effort to take it further down? You decide. – Mike Nakis Sep 28 '16 at 15:34
  • Thanks Mike, Actually I am doing i2c read transaction which will read the register of I2C camera. I hope this clarifies. Let me know if any suggestions. – Titus Sep 28 '16 at 15:37
  • Mike, this is the code. `i2c_read(int handle, int reg, int count, char *buffer ); ret = i2c_read(hHandle, 0x4012, 0x1, buffer); //It will read the address 0x4012 of I2C slave (handle) and update the 1byte return value in buffer` – Titus Sep 28 '16 at 15:45
0

Here are some pseudo code that might help:

do 
{
    // Pseudo code
    start_time = get_current_time(); 

    do 
    {
        temp_reg[0] = read_reg();
        //Read the register here and copy the value into char array (temp_reg

        if (timedout == 1 )
            return -1;//Timedout

        // Pseudo code
        stop_time = get_current_time();
        if (stop_time - start_time > some_limit) break;

    } while (temp_reg[0] != 0 );

    if (temp_reg[0] != 0) 
    {
         usleep(some_time);
         start_time = get_current_time(); 
     }    
} while (temp_reg[0] != 0 );

To turn the pseudo code into real code, see https://stackoverflow.com/a/2150334/4386427

Community
  • 1
  • 1
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63