A Busy Wait Loop For The Eye! [compiler Optimization Rant]

Pratyay DhondPratyay Dhond
4 min read
    for(int i = 25;  i > 0; i--){
        for(int j = 2147483647; j > 0; j--){
            // this loop is supposed to busy wait
        }
    }

I was supposed to implement scheduling and then test which scheduling was better; the one I had written (Priority Scheduling) or the one used prior and by default, Round Robin Scheduling.

The above for loop was what I chose instead of sleep function in my benchmark code. And I executed the code.. and the process returned (even before you read this)

I tried it again with printf() statements to print values of i,j (I was surprised that my laptop is that fast that it executed such gigantic loops in a blink! [I can be dumb at times])

    for(int i = 25;  i > 0; i--){
        for(int j = 2147483647; j > 0; j--){
            printf("%d %d\n",i,j);
        }
    }

When I executed the process this time, it took its time, printing for each loop.
So now I was made to think that the loops were working fine with a statement in it but empty loops were getting ignored.

[Compiler Optimization ;) -> The compiler decides what part of code to keep what not to keep]
If a program execution is similar without some lines of code, the compiler can freely toss those lines of code away at will.
This is usually a really nice thing compiler does (It deserves an ice cream for that) but not today, not while writing a bench marking test


Now Problem #2

I couldn’t use printf() here, as printf() would be bad for my benchmark test

  • printf() works by calling a system call internally, which in turn waits for getting the resources(display device) and outputting to it. \

  • The time taken for this is not fixed and may depend literally on (luck) availability of device at time and other processes (Not ideal for bench marking)

        int i,j;
        for(i = 25;  i > 0; i--){
            for(j = 2147483647; j > 0; j--){
                j--;
            }
        }

Now, I thought this definitely would work, this is a busy loop and not an empty loop, there is something to be done at every iteration.

But to My Freakingggg Horror!!! The compiler optimized it away yet again

Compiler 2 - Pratyay 0 ;()

After reading quite a bunch of articles and stack overflow answers, I realised why it was happening.\ The compiler is a very intelligent program, written by very GoD_LeVeL programmers indeed, it checks our code, loops and realizes that the for loop is ultimately resulting in the value of
i = 0 and j = 0
so, it skips the loop and manually sets i=0 and j=0
This in turn maintains the state of the program variables and the result, but removes the loop.

I was about to Give up and fall to chatgpt

But I decided to wait for some more time (I think chatgpt is great but using it takes us away from interesting things like this I found so I rather use chatgpt less)
and this is when it hit me!
What my professor had said (and a stack overflow article at the time)
The problem was that the compiler was trying to optimize code when I didn’t want it to.
What I could do here is tell the compiler explicitly via code that the variable could change and don’t optimize it!
So that is what I did

        volatile int i,j;
        for(i = 25;  i > 0; i--){
            for(j = 2147483647; j > 0; j--){
                j--;
            }
        }

Volatile! that is all it took
Declaring a variable volatile tells the compiler that the value of that variable may change at anytime and not necessarily by the code given to the compiler itself.
The result? Compiler knows its place and doesn’t optimize it!\

and tadaaa this worked!!!

Compiler 2 : Pratyay 1

but anyways I win compiler ;)

Now I know this might not be the best way to do this, and there are multiple ways to do it, such as
1. using asm, asm volatile to insert NOP instructions in the loop
2. compiling the code with the while loop without optimizations and linking explicitly
3. Many othersssss \

But what mattered here to me is learning that compilers are goddamn intelligent and they optimize code when we aren’t looking!

That’s it for my Compiler Rant! I do love the compiler even though it irritated me somewhat!


These are the articles I referred while I faced the problem\

https://punchlet.wordpress.com/2011/07/01/letter-the-eighth-bedevilling-benchmarks/https://stackoverflow.com/questions/10300253/will-an-empty-for-loop-used-as-a-sleep-be-optimized-awayhttps://stackoverflow.com/questions/7083482/how-can-i-prevent-gcc-from-optimizing-out-a-busy-wait-loop/58758133#58758133


I would love to get some reviews on the post on what could have been better; my view is to keep this kind of material informal so that I can read it again some time later without thinking that it was some documentation but more as a fun blog.

11
Subscribe to my newsletter

Read articles from Pratyay Dhond directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pratyay Dhond
Pratyay Dhond

Learning from my experiences while joking about the stupid mistakes I did in my prior code!