gpt4 book ai didi

clock_gettime() 对比。 gettimeofday() 用于测量 OpenMP 执行时间

转载 作者:太空狗 更新时间:2023-10-29 15:31:53 30 4
gpt4 key购买 nike

我正在编写一些 C 代码,这些代码实现三重嵌套 for 循环以计算矩阵-矩阵乘法,同时使用 OpenMP 对其进行并行化。我试图准确地测量从 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() 的结果长,有时比 clock_gettime() 的结果长一秒以上我使用 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;

这是有原因的吗?使用这两个功能时可能会造成什么不同?我试图更好地理解这两个函数的性质。

最佳答案

elapsed = (end.tv_sec+1E-6*end.tv_usec) - (start.tv_sec+1E-6*start.tv_usec) 在减去类似的值时容易丢失精度都很大。

  1. 使用 elapsed = (end.tv_sec - start.tv_sec) - (start.tv_usec- end.tv_usec)/1E6。这类似于 OP 的第 2 和第 3 代码,但不是第一个。

  2. 保持公平,以一致的顺序获取时间以消除偏见。

    clock_gettime(CLOCK_MONOTONIC, &start1);
    gettimeofday(&start, NULL);

    ...

    // gettimeofday(&end, NULL);
    // clock_gettime(CLOCK_MONOTONIC, &finish1);
    clock_gettime(CLOCK_MONOTONIC, &finish1);
    gettimeofday(&end, NULL);
  3. 次要:第三个非常细微的改进有助于减少一点位(0.5 微秒)的不一致性,它是在滴答变化时开始测试。但注意@Dietrich Epp comment进行替代改进。

    gettimeofday(&t, NULL);
    do {
    gettimeofday(&start, NULL);
    } while (start == t);

或者,使用宽整数数学来避免精度问题

long long elapsed_ns = (1LL*finish1.tv_sec - start1.tv_sec)*1000000000LL + 
finish1.tv_nsec - start1.tv_nsec;

关于clock_gettime() 对比。 gettimeofday() 用于测量 OpenMP 执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39710442/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com