Search code examples
c++gccattributes

Does __attribute__((optimize(0))) apply "recursively"?


Say I want to use a function to measure runtime, I want to avoid the compiler optimizing away expressions just because it thinks they do nothing (they don't, except that I want to measure how long they take to compute). Instead of doing weird gimmicks like adding it up into another variable etc., I found out about __atribute__((optimize(0))) in GCC. However, say I have this code:

__attribute__((optimize(0))) void test(int n) {
    while (n--) {
        foo();
    }
}

int main() {
    std::cout << Timer::measure(test).count() << "ms\n";
}

Would the attribute prevent the compiler from optimizing code inside the function foo() as well? I'm really just trying to test some runtime and reliably and with relative easy prevent the compiler from removing code completely (I want it to optimize the code as good as it can, but not remove it because it doesn't do anything!).

Does that make any sense?


Solution

  • I just figured I could do an experiment (why didn't I think of that sooner), here's what I did:

    // toggle this
    // __attribute__((optimize(0)))
    void waste_time() { for (unsigned i = 100000; i--; ); }
    
    // always leave this on
    __attribute__((optimize(0)))
    void test() {
        for (unsigned i = 1000; i--; ) {
            waste_time();
        }
    }
    
    int main() {
        std::cout << Timer::measure(test).count() << "ms\n";
    }
    

    What I found with -O3:

    waste_time no optimizations: 196.972ms  (obviously the loop is not optimized)
    waste_time w/ optimizations: 0.001995ms (loop is optimized)
    

    For me this makes it very clear, that __attribute__ does not "propagate" to nested function calls, so waste_time() still will be optimized even though test() has the attribute specified.