私は、OpenMP を使用して並列化しながら、行列と行列の乗算を計算するためにトリプル ネストされた for ループを実装する C コードに取り組んでいます。for ループの開始から終了までにかかる時間を正確に測定しようとしています。これまで gettimeofday() を使用してきましたが、for ループの実行にかかった時間を正確に記録しているように感じられない場合があることに気付きました。実際よりも時間がかかったと言っているように見えました。
元のコードは次のとおりです。
struct timeval start end;
double elapsed;
gettimeofday(&start, NULL);
#pragma omp parallel for num_threads(threads) private(i, j, k)
for(...)
{
...
for(...)
{
...
for(...)
{
...
}
}
}
gettimeofday(&end, NULL);
elapsed = (end.tv_sec+1E-6*end.tv_usec) - (start.tv_sec+1E-6*start.tv_usec)
そして、これは clock_gettime() を使用した同じコードです:
struct timespec start1, finish1;
double elapsed1;
clock_gettime(CLOCK_MONOTONIC, &start1);
#pragma omp parallel for num_threads(threads) private(i, j, k)
for(...)
{
...
for(...)
{
...
for(...)
{
...
}
}
}
clock_gettime(CLOCK_MONOTONIC, &finish1);
elapsed1 = (finish1.tv_sec - start1.tv_sec);
elapsed1 += (finish1.tv_nsec - start1.tv_nsec)/1000000000.0;
ループが完了するまでに 3 ~ 4 秒かかります。両方の時間測定を同時に使用してみましたが、gettimeofday() を使用した結果はほとんどの場合、clock_gettime() の結果よりも長く、結果よりも 1 秒以上長くなることもありました。 clock_gettime() を使用して取得していました:
struct timespec start1, finish1;
double elapsed1;
struct timeval start end;
double elapsed;
clock_gettime(CLOCK_MONOTONIC, &start1);
gettimeofday(&start, NULL);
#pragma omp parallel for num_threads(threads) private(i, j, k)
for(...)
{
...
for(...)
{
...
for(...)
{
...
}
}
}
gettimeofday(&end, NULL);
clock_gettime(CLOCK_MONOTONIC, &finish1);
elapsed = (end.tv_sec+1E-6*end.tv_usec) - (start.tv_sec+1E-6*start.tv_usec)
elapsed1 = (finish1.tv_sec - start1.tv_sec);
elapsed1 += (finish1.tv_nsec - start1.tv_nsec)/1000000000.0;
これには理由がありますか?これら 2 つの機能を使用する際に違いが生じる原因は何ですか? これら 2 つの機能の性質をよりよく理解しようとしています。