0

我想在循环中测量函数开始到结束之间的时间。这种差异将用于设置内部 while 循环的循环数量,这在这里做了一些不重要的事情。

我想像这样计时功能:

#include <wiringPi.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#define BILLION 1E9

float hz = 1000;
long int nsPerTick = BILLION/hz;

double unprocessed = 1;
struct timespec now;
struct timespec last;
clock_gettime(CLOCK_REALTIME, &last);

[ ... ]

while (1) 
{
    clock_gettime(CLOCK_REALTIME, &now); 

    double diff = (last.tv_nsec - now.tv_nsec );

    unprocessed = unprocessed + (diff/ nsPerTick);
    clock_gettime(CLOCK_REALTIME, &last);


    while (unprocessed >= 1) { 
            unprocessed --;
            DO SOME RANDOM MAGIC;
            }
    }

计时器之间的差异始终为负。有人告诉我这是错误所在:

    if ( (last.tv_nsec - now.tv_nsec)<0) {
         double diff = 1000000000+ last.tv_nsec - now.tv_nsec;
         }
    else {
         double diff = (last.tv_nsec - now.tv_nsec );
    }

但是,我的变量差异总是像“-1095043244”这样的负数(但在函数期间花费的时间当然是正数)。

怎么了?

4

4 回答 4

1

我只是在用类似的方法和类似的问题调查 Pi 的时间安排。我的想法是:

您不必使用双倍。事实上,您也不需要纳秒,因为 Pi 上的时钟无论如何都具有 1 微秒的精度(这是 Broadcom 的做法)。我建议您使用 gettimeofday() 来获取微秒而不是纳秒。那么计算就很简单了,就是:

number of seconds + (1000 * 1000 * number of micros) 

您可以简单地将其计算为无符号整数。

我为此实现了方便的 API:

typedef struct
{
    struct timeval startTimeVal;
} TIMER_usecCtx_t;

void TIMER_usecStart(TIMER_usecCtx_t* ctx)
{
    gettimeofday(&ctx->startTimeVal, NULL);
}

unsigned int TIMER_usecElapsedUs(TIMER_usecCtx_t* ctx)
{
    unsigned int rv;

    /* get current time */
    struct timeval nowTimeVal;
    gettimeofday(&nowTimeVal, NULL);

    /* compute diff */
    rv = 1000000 * (nowTimeVal.tv_sec - ctx->startTimeVal.tv_sec) + nowTimeVal.tv_usec - ctx->startTimeVal.tv_usec;

    return rv;
}

用法是:

TIMER_usecCtx_t timer;
TIMER_usecStart(&timer);

while (1)
{
    if (TIMER_usecElapsedUs(timer) > yourDelayInMicroseconds)
    {
        doSomethingHere();
        TIMER_usecStart(&timer);
    }
}

另请注意,对 Pi 的 gettime() 调用几乎需要 1 [us] 时间才能完成。因此,如果您需要大量调用 gettime() 并且需要更高的准确性,请使用一些更高级的获取时间的方法...我在这篇关于 Pi 获取时间调用的简短文章中对此进行了更多解释

于 2014-12-29T11:52:55.747 回答
1

你的第一个问题是你有`last.tv_nsec - now.tv_nsec,这是错误的方式。

last.tv_nsec是过去的(假设它设置为 1),并且now.tv_nsec总是更晚(例如,8ns 之后,所以它是 9)。在这种情况下,last.tv_nsec - now.tv_nsec== 1 - 9 == -8。

另一个问题是 tv_nsec 不是以纳秒为单位的时间:为此,您需要将时间(以秒为单位)乘以十亿并加上。因此,要获得现在和上次之间的 ns 差异,您需要:

((now.tv_sec - last.tv_sec) * ONE_BILLION) + (now.tv_nsec - last.tv_nsec)

(注意,尽管 now.tv_nsec 和 last.tv_nsec 都小于 10 亿,但我仍然有点惊讶,但从另一个中减去一个得到的值小于 -1000000000,所以我可能还缺少一些东西。 )

于 2013-02-03T20:22:12.653 回答
0

好吧,我不知道 C,但如果它是 Raspberry Pi 上的时间问题,它可能与芯片上缺少 RTC(实时时钟)有关。

于 2013-06-10T19:04:36.240 回答
0

你不应该存放last.tv_nsec - now.tv_nsec在双份中。

如果您查看 的文档time.h,您可以看到它tv_nsec存储为 long。因此,您将需要以下内容:

long diff = end.tv_nsec - begin.tv_nsec

话虽如此,仅比较纳秒可能会出错。您还需要查看秒数。因此,要将所有内容转换为秒,您可以使用以下命令:

long nanosec_diff = end.tv_nsec - begin.tv_nsec;
time_t sec_diff = end.tv_sec - begin.tv_sec; // need <sys/types.h> for time_t
double diff_in_seconds = sec_diff + nanosec_diff / 1000000000.0

另外,请确保您始终从开始时间中减去结束时间(否则您的时间仍然是负数)。

你去吧!

于 2014-02-17T01:53:30.753 回答