私はこのようなものを持っています:
clock_t start, end;
start=clock();
something_else();
end=clock();
printf("\nClock cycles are: %d - %d\n",start,end);
そして、私は常に出力として「クロックサイクルは次のとおりです:0-0」を取得します
なぜこれが起こるのか考えはありますか?
(詳細を説明するために、something_else()関数は、モンゴメリ表現を使用して左から右へのべき乗を実行します。さらに、something_else()関数が実際に無視できないほどの時間を要するかどうかはわかりません。)
これはLinux上にあります。 uname-aの結果は次のとおりです。
Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux
clock
関数はCPUクロックサイクルを測定しません。
Cは、clock
"は、実装の最良の近似値を、プログラムが最初から使用したプロセッサ時間に返します。プログラムの呼び出しにのみ関連する実装定義の時代のことです。」
2つの連続するclock
呼び出しの間に、プログラムがclock
関数の1つの単一性よりも短い時間で済む場合、0
を取得できます。
POSIX clock
は、CLOCKS_PER_SEC
とのユニティを1000000として定義します(ユニティは1マイクロ秒になります)。
http://pubs.opengroup.org/onlinepubs/009604499/functions/clock.html
X86/x64でクロックサイクルを測定するには、インラインアセンブリを使用して、CPUタイムスタンプカウンターレジスタrdtsc
のクロックカウントを取得できます。
その理由はあなたのsomething_else()
はclock()
の精度を超えるほどの時間を消費しないからだと思います。その結果、clock()
を2回呼び出してみましたが、start
とend
はどちらもゼロですが、その間に時間のかかる作業を行うと、結果は妥当です。
これが私のテストコードスニペットです:
_int main(void) {
clock_t start, end;
start = clock();
int c;
for (int i = 0; i < 100; i++) {
for (int j = 0; j < (1<<30); j++) {
c++;
}
}
end = clock();
printf("start = %d, end = %d\n", start, end);
return 0;
}
_
そして、私のコンピューターでの結果は次のとおりです。
_start = 0, end = 27700000
_
また、2つのヒント:
something_else()
は時間がかかると思うかもしれませんが、コンパイラーはそれらの操作(特にループ)を無意味だと考えるので無視するかもしれません。sizeof(clock_t)
を使用して、_clock_t
_のサイズを確認します。さて、something_else()
にかかる時間は必要ですか?これを試して:
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main(void) {
struct timeval start, end;
long mtime, secs, usecs;
gettimeofday(&start, NULL);
something_else();
gettimeofday(&end, NULL);
secs = end.tv_sec - start.tv_sec;
usecs = end.tv_usec - start.tv_usec;
mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;
printf("Elapsed time: %ld millisecs\n", mtime);
return 0;
}
_CLOCKS_PER_SEC
_の_time.h/clock.h
_の値を確認してください。たとえば、私のシステムでは(Windows7のDevCpp)は単なる_1000
_です。私のプログラムに関する限り、毎秒1000ティックがあります。 _something_else
_はマイクロ秒単位で実行されます。したがって、clock()
は、関数呼び出しの前後の両方でゼロを返します。
私のシステムでは、あなたの_something_else
_をこのような時間のかかるルーチンに置き換えると
_for (unsigned i=0xFFFFFFFF;i--;);
start=clock();
for (unsigned i=0xFFFFFFFF;i--;);
end=clock();
_
私は得る
クロックサイクルは次のとおりです:10236-20593
Linuxボックスの1つで、_bits/time.h
_に次のものがあります。
_/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
# define CLOCKS_PER_SEC 1000000l
_
したがって、clock()
の戻り値を分析する前に、これを考慮してください。
Clock()を使用して時間を測定する正しい方法は次のとおりです。
printf("\nTime elapsed: %.2f\n",1.0*(end-start)/CLOCKS_PER_SEC);
これは、clock_tがint、またはその他のタイプであることが保証されていないためです。
以下の小さなプログラムを使用して、実時間とCPU時間を調査しました。
私のテストシステムでは、これは印刷されます
CLOCKS_PER_SEC 1000000
CPU time usage resolutio
nは0.010000 seconds
のようです
gettimeofdayが9634 uS
によって変更された場合、CPU時間が0.010000
によって変更された場合
gettimeofdayの解像度は1米ドルのようです
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>
int main(int argc, char** argv) {
struct timeval now; // wall clock times
struct timeval later;
clock_t tNow = clock(); // clock measures CPU time of this Linux thread
gettimeofday(&now, NULL); // wall clock time when CPU time first read
clock_t tLater = tNow;
while (tNow == tLater)
tLater = clock(); // consume CPU time
gettimeofday(&later, NULL); // wall clock time when CPU time has ticked
printf("CLOCKS_PER_SEC %ld\n",CLOCKS_PER_SEC);
double cpuRes = (double)(tLater - tNow)/CLOCKS_PER_SEC;
printf("CPU time usage resolution looks to be %f seconds\n", cpuRes);
unsigned long long nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
nowUs += (unsigned long long)now.tv_usec;
unsigned long long laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
laterUs += (unsigned long long)later.tv_usec;
printf("gettimeofday changed by %d uS when CPU time changed by %f seconds\n", (int)(laterUs - nowUs), cpuRes);
// now measure resolution of gettimeofday
gettimeofday(&now, NULL);
later = now;
while ((now.tv_sec == later.tv_sec) && (now.tv_usec == later.tv_usec))
gettimeofday(&later, NULL);
nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
nowUs += (unsigned long long)now.tv_usec;
laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
laterUs += (unsigned long long)later.tv_usec;
printf("gettimeofday resolution looks to be %d us\n", (int)(laterUs - nowUs));
}