在C代码中需要一些帮助以进行优化(轮询+延迟/睡眠)

时间:2016-09-28 14:47:55

标签: c linux

目前我正在轮询寄存器以获得预期值,现在我想降低CPU使用率并提高性能。 所以,我认为,如果我们进行特定时间的轮询(说出10ms),如果我们没有获得预期值,那么等待一段时间(如udelay(10 * 1000)或usleep(10 * 1000)延迟/以ms为单位睡觉然后继续进行轮询以获得更多的额外时间(比如100毫秒),如果你没有得到预期值,那么就进行睡眠/延迟100毫秒.....反之亦然...需要直到它达到最大超时值。

如果有的话,请告诉我。

这是旧代码:

#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");
}

现在我想优化并降低CPU使用率,并希望提高性能。

任何人都可以帮我解决这个问题吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

  

目前我正在轮询寄存器以获得预期值[...]

哇,哇哇,在这里等一下,这句话背后隐藏着一个巨大的故事;什么是“登记册”?什么是“预期价值”? read_reg()做了什么?你在轮询一些外部硬件吗?那么,这完全取决于硬件的行为方式。

有两种可能性:

  1. 您的硬件会缓冲它产生的值。这意味着硬件将保持每个值可用,直到您阅读它;它会检测您何时读取该值,然后它将提供下一个值。

  2. 您的硬件没有缓冲值。这意味着值实时可用,每个时间长度未知,并且它们将以只有您的硬件知道的速率替换为新值。

  3. 如果您的硬件正在缓冲,那么您不必担心某些值可能会丢失,因此根本不需要轮询:只需尝试一次读取下一个值,如果不是你期待什么,睡一会儿。当你四处阅读它时,每个值都会存在。

    如果您的硬件缓冲,则没有适用于您的轮询和休眠策略。您的硬件必须提供中断,并且您必须编写一个中断处理例程,该例程将从可用时刻开始尽快读取每个新值

答案 1 :(得分:0)

以下是一些可能有用的伪代码:

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 );

要将伪代码转换为实际代码,请参阅https://stackoverflow.com/a/2150334/4386427