静态预计算优化 [英] static pre-calculation optimization in clang

查看:368
本文介绍了静态预计算优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有

#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <math.h>

int fib(int n) {
    return n < 2 ? n : fib(n-1) + fib(n-2);
}

double clock_now()
{
    struct timeval now;

    gettimeofday(&now, NULL);
    return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
}

#define NITER 5

code> main(),我这样做一个简单的基准:

and in my main(), I'm doing a simple benchmark like this:

printf("hi\n");
double t = clock_now();
int f = 0;
double tmin = INFINITY;
for (int i=0; i<NITER; ++i) {
    printf("run %i, %f\n", i, clock_now()-t);
    t = clock_now();
    f += fib(40);
    t = clock_now()-t;
    printf("%i %f\n", f, t);
    if (t < tmin) tmin = t;
    t = clock_now();
}
printf("fib,%.6f\n", tmin*1000);

当我使用 clang -O3 LLVM 5.0从Xcode 5.0.1),它总是打印零时间,除了 for -loop,即:

When I compile with clang -O3 (LLVM 5.0 from Xcode 5.0.1), it always prints out zero time, except at the init of the for-loop, i.e. this:

hi
run 0, 0.866536
102334155 0.000000
run 1, 0.000001
204668310 0.000000
run 2, 0.000000
307002465 0.000000
run 3, 0.000000
409336620 0.000000
run 4, 0.000001
511670775 0.000000
fib,0.000000

它似乎静态地预先计算 fib(40)某处。对?开始时的奇怪延迟(0.8秒)可能是因为它加载了缓存?

It seems that it statically precalculates the fib(40) and stores it somewhere. Right? The strange lag at the beginning (0.8 secs) is probably because it loads that cache?

我这样做是为了基准测试。 C编译器应该尽可能多地优化 fib()。但是,我不希望它在编译时预先计算它。所以基本上我希望所有的代码尽可能地优化,但不是 main()(或至少不是这个特定的优化)。我可以这样做吗?

I'm doing this for benchmarking. The C compiler should optimize fib() itself as much as it can. However, I don't want it to precalculate it already at compile time. So basically I want all code optimized as heavily as possible, but not main() (or at least not this specific optimization). Can I do that somehow?

在这种特定情况下,无论如何,什么优化?

What optimization is it anyway in this specific case? It's somehow strange and quite nice.

推荐答案

我发现一个解决方案,通过标记某些数据 volatile 。 Esp,我做的是:

I found a solution by marking certain data volatile. Esp, what I did was:

volatile int f = 0;
//...
    volatile int FibArg = 40;
    f += fib(FibArg);

这样,它强制编译器读取 FibArg 调用该函数时,它强制它不假定它是常量。因此,它必须调用函数来计算它。

That way, it forces the compiler to read FibArg when calling the function and it forces it to not assume that it is constant. Thus it must call the function to calculate it.

对于我的编译器, volatile int f 但它可能在未来,当编译器计算出 fib 没有副作用,其结果也不是 f

The volatile int f was not necessary for my compiler at the moment but it might be in the future when the compiler figures out that fib has no side effects and its result nor f is every used.

请注意,这还不是结束。未来的编译器可以推进到目前为止,它猜测 40 fib 的可能参数。也许它构建一个可能的值的数据库。对于最可能的值,它构建了一个小缓存。当调用 fib 时,它会快速运行时检查它是否有被缓存的值。当然,运行时检查增加了一些开销,但也许编译器估计这些开销对于某些特定的代码与缓存的速度有关。

Note that this is still not the end. A future compiler could have advanced so far that it guesses that 40 is a likely argument for fib. Maybe it builds a database for likely values. And for the most likely values, it builds up a small cache. And when fib is called, it does a fast runtime-check whether it has that value cached. Of course, the runtime-check adds some overhead but maybe the compiler estimates that this overhead is minor for some particular code in relation to the speed gained by the cached.

I不知道一个编译器是否会做这样的优化,但它可以。轮廓引导优化(PGO)已经朝这个方向发展了。

I'm not sure if a compiler will ever do such optimization but it could. Profile Guided Optimization (PGO) goes already in that direction.

这篇关于静态预计算优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆