gpt4 book ai didi

c - 为什么 atan 的第一个调用比下一个慢得多?

转载 作者:太空宇宙 更新时间:2023-11-04 03:37:20 27 4
gpt4 key购买 nike

下面的代码演示了 atan 的计算时间可以有很大的不同:

#include <cstdio>
#include <cstdlib>
#include <cmath>

#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}

int main() {
double worst_time = 0.0;
double best_time = 1e6;

volatile double x0 = -M_PI/2.0;
volatile double foo = atan(x0); // SLOW CALL HERE
volatile double sum = 0.0; // volatile to avoid having tan() call optimized away
for (double x = x0; x < M_PI/3.0; x += 0.1) {
volatile double y = x;
const double start = get_time();
asm volatile ("":::"memory"); // avoid reordering in -O3
const double value = atan(y);
asm volatile ("":::"memory"); // avoid reordering
const double end = get_time();
sum += value;

const double delta = end - start;
if (delta > worst_time) {
worst_time = delta;
}
if (delta < best_time) {
best_time = delta;
}
printf("* %f (value: %f)\n", delta, y);
}

printf("%f / %f\n", worst_time, best_time);

printf("%f\n", foo);
}

从我的机器来看,最差时间约为 15us,而最佳时间为 0(太小而无法测量)。

我机器上的平均时间(此处未显示)约为 1 或 2 us。

我尝试了不同的编译标志(-O3、静态链接到 libm 等),但我找不到导致最坏时间变慢的原因。有什么想法吗?

编辑:我使用的是 Ubuntu 14.04 - gcc 4.8.4

edit2:用 atan 替换 atan2。我对 atan2 是分段定义的事实不感兴趣,不同的分支可能需要不同的时间。我有兴趣消除即使调用 atan 而不是 atan2 也会出现的异常值。

编辑3:

* 0.000015 (value: -1.570796)
* 0.000000 (value: -1.470796)
* 0.000001 (value: -1.370796)
* 0.000001 (value: -1.270796)
* 0.000000 (value: -1.170796)
* 0.000002 (value: -1.070796)
* 0.000000 (value: -0.970796)
* 0.000001 (value: -0.870796)
* 0.000000 (value: -0.770796)
* 0.000000 (value: -0.670796)
* 0.000001 (value: -0.570796)
* 0.000000 (value: -0.470796)
* 0.000003 (value: -0.370796)
* 0.000001 (value: -0.270796)
* 0.000000 (value: -0.170796)
* 0.000000 (value: -0.070796)
* 0.000001 (value: 0.029204)
* 0.000000 (value: 0.129204)
* 0.000002 (value: 0.229204)
* 0.000001 (value: 0.329204)
* 0.000000 (value: 0.429204)
* 0.000001 (value: 0.529204)
* 0.000001 (value: 0.629204)
* 0.000001 (value: 0.729204)
* 0.000001 (value: 0.829204)
* 0.000001 (value: 0.929204)
* 0.000000 (value: 1.029204)
0.000015 / 0.000000 / 0.000001

编辑4:

看来第一个电话是罪魁祸首!循环外的调用被编译器优化掉了,如果我们强制在循环外为 x0 计算 atan,所有调用都相当快......

* 0.000000 (value: -1.570796)
* 0.000001 (value: -1.470796)
* 0.000000 (value: -1.370796)
* 0.000002 (value: -1.270796)
* 0.000001 (value: -1.170796)
* 0.000001 (value: -1.070796)
* 0.000000 (value: -0.970796)
* 0.000000 (value: -0.870796)
* 0.000000 (value: -0.770796)
* 0.000001 (value: -0.670796)
* 0.000000 (value: -0.570796)
* 0.000000 (value: -0.470796)
* 0.000006 (value: -0.370796)
* 0.000001 (value: -0.270796)
* 0.000002 (value: -0.170796)
* 0.000001 (value: -0.070796)
* 0.000000 (value: 0.029204)
* 0.000001 (value: 0.129204)
* 0.000003 (value: 0.229204)
* 0.000000 (value: 0.329204)
* 0.000000 (value: 0.429204)
* 0.000000 (value: 0.529204)
* 0.000001 (value: 0.629204)
* 0.000000 (value: 0.729204)
* 0.000000 (value: 0.829204)
* 0.000000 (value: 0.929204)
* 0.000000 (value: 1.029204)
0.000006 / 0.000000

https://ideone.com/vtUuE6

最佳答案

时间差异实际上是由页面错误(!)引起的。第一次调用该函数时,访问包含atan2代码的页面并发生页面错误。使用 mlockall() 应该可以改善这种情况。

关于c - 为什么 atan 的第一个调用比下一个慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467813/

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