[C++] C ++ / POSIX最も効率的な方法でミリ秒のタイムスタンプを取得するには?


Answers

あなたの2つの例は同等ではないことに注意してください。 clock_gettime(CLOCK_REALTIME、...)はウォールクロック時間を測定するのに対し、times(2)はCPU消費時間を測定します。

つまり、clock_gettimeや古いgettimeofdayなどのwallclockタイマーはtimes()やgetrusage()などのCPUタイマーよりもはるかに高速です。

すでに述べたように、あなたのタイミング機能はポーリング以外にほとんど何もしていないので、CPU時間を大幅に使い果たしています。 それが問題であれば、例えばnanosleep()やclock_nanosleep()を呼び出して少し待ってください。

私はあなたの最良の選択肢は、CLOCK_REALTIMEの代わりにCLOCK_MONOTONICで、clock_gettime()を使うことだと思います。

Question

私はi2cバス動作のためにオープンソースライブラリを使用しています。 このライブラリでは、実際のタイムスタンプをミリ秒単位で取得する関数を頻繁に使用しています。

コール例:

nowtime = timer_nowtime();
while ((i2c_CheckBit(dev) == true) && ((timer_nowtime() - nowtime) < I2C_TIMEOUT));

このi2cライブラリを使用するアプリケーションは、多くのCPU容量を使用します。 私は、実行中のプログラムが最も時間が関数timer_nowtime()呼び出していることを理解しました。

元の関数:

unsigned long timer_nowtime(void) {        
    static bool usetimer = false;
    static unsigned long long inittime;
    struct tms cputime;

    if (usetimer == false)
    {
        inittime  = (unsigned long long)times(&cputime);
        usetimer = true;
    }

    return (unsigned long)((times(&cputime) - inittime)*1000UL/sysconf(_SC_CLK_TCK));
}

私の目標は、この機能の効率を改善することです。 私はこの方法で試しました:

struct timespec systemtime;

clock_gettime(CLOCK_REALTIME, &systemtime);
//convert the to milliseconds timestamp
// incorrect way, because (1 / 1000000UL) always returns 0 -> thanks Pace
//return (unsigned long) ( (systemtime.tv_sec * 1000UL) + (systemtime.tv_nsec
//              * (1 / 1000000UL)));
return (unsigned long) ((systemtime.tv_sec * 1000UL)
            + (systemtime.tv_nsec / 1000000UL));

残念ながら、私はこの関数をインラインで宣言することはできません。

ms解像度で実際のタイムスタンプを取得する方が効率的ですか? 私は確かにそれを行うためのより毎回の方法があります。 助言がありますか?

ありがとう。




あなたのプログラムが最近のIntel / AMDプロセッサ上でのみ実行されますが、あまり最近のものではない場合(クロック調整はあまりうまく処理されません)、 RDTSCアセンブリ命令がタイムスタンプを取得する最良の方法です。 解像度はプロセッサの実際のクロックに近く、システムとは独立しています(これは割り込みによっても偏っていることを意味します。ケーキを食べることはできません)。

このページにはCの例があります。