7

Linuxで経過時間を測定しようとしています。私の答えはゼロを返し続けますが、これは私には意味がありません。以下は、私のプログラムで時間を測定する方法です。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

main()
{
    double p16 = 1, pi = 0, precision = 1000;
    int k;
    unsigned long micros = 0;
    float millis = 0.0;
    clock_t start, end;
    start = clock();
    // This section calculates pi
    for(k = 0; k <= precision; k++)
    {
        pi += 1.0 / p16 * (4.0 / (8 * k + 1) - 2.0 / (8 * k + 4) - 1.0 / (8 * k + 5) - 1.0 / (8 * k + 6));
        p16 *= 16;
    }
    end = clock();
    micros = end - start;
    millis = micros / 1000;
    printf("%f\n", millis); //my time keeps being returned as 0

    printf("this value of pi is  : %f\n", pi);
}
4

6 に答える 6

19

3 つの選択肢

  1. clock()
  2. gettimeofday()
  3. clock_gettime()

clock_gettime()ナノ秒の精度まで上がり、4 クロックをサポートします。

  • CLOCK_REALTIME

    システム全体のリアルタイム クロック。このクロックを設定するには、適切な権限が必要です。

  • CLOCK_MONOTONIC

    設定することができず、特定されていない開始点からの単調な時間を表す時計。

  • CLOCK_PROCESS_CPUTIME_ID

    CPU からのプロセスごとの高解像度タイマー。

  • CLOCK_THREAD_CPUTIME_ID

    スレッド固有の CPU タイム クロック。

として使用できます

#include <time.h>

struct timespec start, stop;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

/// do something

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);

double result = (stop.tv_sec - start.tv_sec) * 1e6 + (stop.tv_nsec - start.tv_nsec) / 1e3;    // in microseconds
于 2015-07-03T09:09:50.083 に答える
4

まず、浮動小数点演算を使用する必要があります。より大きな整数値で割った整数値は、常にゼロになります。

もちろん、開始時刻と終了時刻を取得する間に実際に何かを行う必要があります。


ちなみに、アクセスできる場合は、解像度が高いため、gettimeofday通常は優先されます。clockまたはclock_gettime、どちらがさらに高い解像度を持っているかもしれません。

于 2013-02-04T08:25:58.837 に答える
2

書かれたコードには 2 つの問題があります。

  1. によるとman 3 clock、 の解像度はclock()1CLOCKS_PER_SEC秒あたりの増分です。最近の Cygwin システムでは、200 です。変数の名前に基づいて、値は 1,000,000 であると予想されます。

  2. この行:

    millis = micros / 1000;
    

    両方のオペランドが整数であるため、商は整数として計算されます。浮動小数点型への昇格は、 への代入時に発生しますmillis。この時点で、小数部分は既に破棄されています。

を使用して経過秒数を計算するには、次のclock()ようにする必要があります。

clock_t start, end;
float seconds;
start = clock();
// Your code here:
end = clock();
seconds = end - start; // time difference is now a float
seconds /= CLOCKS_PER_SEC; // this division is now floating point

ただし、ほとんどの場合、ミリ秒の精度は得られません。そのためには、gettimeofday()またはを使用する必要がありますclock_gettime()。さらに、非常に小さな差で非常に大きな数を減算することになる可能性が高いため、おそらくdoubleの代わりに使用することをお勧めします。float使用例は次のclock_gettime()ようになります。

#include <time.h>
/* Floating point nanoseconds per second */
#define NANO_PER_SEC 1000000000.0

int main(void)
{
    struct timespec start, end;
    double start_sec, end_sec, elapsed_sec;
    clock_gettime(CLOCK_REALTIME, &start);
    // Your code here
    clock_gettime(CLOCK_REALTIME, &end);
    start_sec = start.tv_sec + start.tv_nsec / NANO_PER_SEC;
    end_sec = end.tv_sec + end.tv_nsec / NANO_PER_SEC;
    elapsed_sec = end_sec - start_sec;
    printf("The operation took %.3f seconds\n", elapsed_sec);

    return 0;
}

は浮動小数点値であるためNANO_PER_SEC、除算は浮動小数点で実行されます。

ソース: 、、および
manのページ。Cプログラミング言語カーニハンとリッチーclock(3)gettimeofday(3)clock_gettime(3)

于 2016-10-16T17:51:01.087 に答える
1

Sunil D S の答えを試してみてください。ただし、次のように、micros を unsigned long から float または double 型に変更します。

double micros;
float seconds;

clock_t start, end;

start = clock();

/* Do something here */

end = clock();

micros = end - start;
seconds = micros / 1000000;

または、次のように rusage を使用することもできます。

struct rusage before;

struct rusage after;

float a_cputime, b_cputime, e_cputime;

float a_systime, b_systime, e_systime;

getrusage(RUSAGE_SELF, &before);

/* Do something here! or put in loop and do many times */

getrusage(RUSAGE_SELF, &after);

a_cputime = after.ru_utime.tv_sec + after.ru_utime.tv_usec / 1000000.0;

b_cputime = before.ru_utime.tv_sec + before.ru_utime.tv_usec / 1000000.0;

e_cputime = a_cputime - b_cputime;

a_systime = after.ru_stime.tv_sec + after.ru_stime.tv_usec / 1000000.0;

b_systime = before.ru_stime.tv_sec + before.ru_stime.tv_usec / 1000000.0;

e_systime = a_systime - b_systime;


printf("CPU time (secs): user=%.4f; system=%.4f; real=%.4f\n",e_cputime, e_systime, seconds);

単位と精度は、測定する時間によって異なりますが、どちらもミリ秒の妥当な精度を提供する必要があります。

于 2013-12-09T07:07:45.137 に答える
1

除算すると小数になる可能性があるため、ミリ秒数を格納するために浮動小数点数が必要です。浮動小数点を使用しない場合、小数部分は切り捨てられます。あなたのコードでは、開始と終了はほとんど同じです。したがって、long に格納した場合の除算後の結果は "0" です。

unsigned long micros = 0;
float millis = 0.0;
clock_t start, end;

start = clock();

//code goes here

end = clock();

micros = end - start;
millis = micros / 1000;
于 2013-02-04T08:27:49.680 に答える