実行時間の計測(C言語)
実行時間について教えてください。
実行時間について不可思議な現象が起きたので疑問に思いました。
C言語においてfor文の2億回ループする場合の実行時間を計測し、計測する内容を変えます。
以下のプログラムのように、時間を計測します。
--------------------
・
・
gettimeofday(&t0, NULL);
(計測したい処理)
gettimeofday(&t1, NULL);
・
・
---------------------
(計測したい処理)に以下のようなプログラムを入れ時間を計測しました。
以下、(計測したい処理) → それにかかった実行時間
<実行結果 書式(計測したい処理) → 計測された時間 >
(1)for ( i = 0; i < 2000000000; i++); → 5.412432 sec
(2)for ( i = 0; i < 2000000000; i++, a++); → 5.401164 sec
(3)for ( i = 0; i < 2000000000; i++, a++,a++); → 9.340447 sec
(4)for ( i = 0; i < 2000000000; i++, a++,a++,a++); → 13.985456 sec
この結果を受けての疑問(1)
(2)~(4)までは、加算する回数(a++)が2倍、3倍と増えたため、線形的に実行時間が増えるという理屈で納得できるのですが、
(1)~(2)について、加算する回数(a++)が増えているのに、なぜ実行時間が(1)と(2)では変わらないのか。
アセンブラに直すと、確かに加算回数は増えているはずです。
<実行結果 書式(計測したい処理) → 計測された時間 >
(5)for ( i = 0; i < 2000000000; i++); → 5.412432 sec
(6)for ( i = 0; i < 2000000000; i++, a++); → 5.401164 sec
(7)for ( i = 0; i < 2000000000; i++, a++,b++); → 4.019215 sec
(8)for ( i = 0; i < 2000000000; i++, a++,b++,c++); → 4.008310 sec
実行結果を受けての疑問(2)
なぜ、(6)~(7)では、加算される回数は増えているにも関わらず、
(5)より実行時間は短くなっているのか。
((3)と(7)の時間差があることについは、対象となるレジスタが違うため、並行処理をしていると推察できることはわかります。今回は(5)~(8)にかけて、なぜ実行時間が短くなるのかという質問です。)
<前提>
・前提として、プログラム内容に間違いはない。
・バックグラウンドで動いているプログラムの影響は受けていないとします。
(何度も実行して確認しているので常にこのような結果が得られました。)
疑問1、2について、推測できる理由を教えてください。
<環境>
・Windows7 Corei5 上で VMwareによってUbuntuで実行しています。(VMwareのコア数の設定は1)
・メモリはWindowsOS、VMwareによる設定共に2GB
<ソース>
#include <stdio.h>
#include <sys/time.h> // gettimeofday
int main()
{
struct timeval t0, t1;
long l;
long i;
long h;
long j;
long k;
i = 0;
h = 0;
l = 0;
j = 0;
k = 0;
gettimeofday(&t0, NULL);
for ( i = 0; i < 2000000000; i++,l++,h++,j++); /*この部分の加算を変更して計測しています。*/
gettimeofday(&t1, NULL);
printf("i = %ld, l = %ld, h=%ld \n",i,l,h);
t1.tv_sec -= t0.tv_sec;
if (t1.tv_usec < t0.tv_usec) {
t1.tv_sec -= 1;
t1.tv_usec += 1000000 - t0.tv_usec;
} else {
t1.tv_usec -= t0.tv_usec;
}
printf("%d.%06d sec\n", t1.tv_sec, t1.tv_usec);
}
わかる方、回答を何卒お願いします。
(解答に必要な条件が足りないのでしたら、教えてください。すぐに追記します。)