11

I have code in my C++ application that generally does this:

bool myFlag = false;
while (/*some finite condition unrelated to myFlag*/) {
    if (...) {
        // statements, unrelated to myFlag
    } else {
        // set myFlag to true, perhaps only if it was false before?
    }
}
if (myFlag) {
    // Do something...
}

The question I have pertains to the else statement of my code. Basically, my loop may set the value of myFlag from false to true, based on a certain condition not being met. Never will the flag be unset from true to false. I would like to know what statement makes more sense performance-wise and perhaps if this issue is actually a non-issue due to compiler optimization.

myFlag = true;

OR

if (!myFlag) myFlag = true;

I would normally choose the former because it requires writing less code. However, I began to wonder that maybe it involved needless writing to memory and therefore the latter would prevent needless writing if myFlag was already true. But, would using the latter take more time because there is a conditional statement and therefore compile code using more instructions?

Or maybe I am over-thinking this too much...


UPDATE 1

Just to clarify a bit...the purpose of my latter case is to not write to memory if the variable was already true. Thus, only write to memory if the variable is false.

4
  • 18
    You are over-thinking this too much. Commented Feb 22, 2013 at 22:00
  • 1
    Typically, myFlag = true will be faster however when you want to know what is faster you have to profile it on your own system. Commented Feb 22, 2013 at 22:05
  • You would just replacing a needless write with a needless read and branch, and guess which is slower. Commented Feb 22, 2013 at 23:02
  • 1
    The only time you need to worry about stuff like this is when you are writing to variables that are being shared with other threads. If myFlag was shared (it isn't in your case) then writing to it indiscriminately would make the cache-line dirty which would snoop it out of all other cores that may have had a clean copy, and you have to consider false sharing - but then I'm over-thinking the answer :-) Commented Feb 28, 2013 at 4:15

6 Answers 6

14

You're almost certainly better off just using myFlag = true;.

About the best you can hope for from the if (!myFlag) myFlag = true; is that the compiler will notice that the if is irrelevant and optimize it away. In particular, the if statement needs to read the current value of myFlag. If the value isn't already in the cache, that means the instruction will stall while waiting for the data to be read from memory.

By contrast, if you just write (without testing first) the value can be written to a write queue, and then more instructions can execute immediately. You won't get a stall until/unless you read the value of myFlag (and assuming it's read reasonably soon after writing, it'll probably still be in the cache, so stalling will be minimal).

Sign up to request clarification or add additional context in comments.

2 Comments

It is possible to have the CPU stall on write but not on read. It's just not very likely.
@JackAidley: Oh, yeah, at least in theory (e.g., if you have only write-through caching). The circumstances to lead to writing being slower are beyond "not very likely", somewhere on the edge between "extremely rare" and "purely theoretical" though.
3

CPU-cycle wise, prefer myFlag = true; Think about it: even if the compiler makes no optimization (not really likely), just setting it takes one asm statement, and going through the if takes at least 1 asm statement.

So just go with the assignment.

And more importantly, don't try to make hypotheses on such low-level details, specific compiler optimizations can totally go against intuition.

2 Comments

If the bool is in memory, the read/write of memory is likely to be the bottleneck not the CPU.
ok, but anyway you'll have to get it from memory to evaluate the if, and then it will most likely stay in cache memory. So access to memory is needed in both cases unless it's already in cache.
2

You do realize that the check is moot right? If you blindly set it to true and it was not set, you are setting it. If it was already true, then there is no change and you are not setting it, so you effectively can implement it as:

myFlag = true;

Regarding the potential optimizations, to be able to test, the value must be in the cache, so most of the cost is already paid. On the other hand, the branch (if the compiler does not optimize the if away, which most will) can have a greater impact in performance.

Comments

0

You are most likely over-thinking the problem as others already mentioned, so let me do the same. The following might be faster if you can afford to double the statements unrelated to myFlag. In fact, you can get rid of myFlag. OK, here we go:

while (/*some finite condition*/) {
    if (...) {
        // statements
    } else {
        while (/*some finite condition*/) {
            if (...) {
               // statements, repeated
            }
        }
        // Do something (as if myFlag was true in the OPs example)
        break;
    }
}

As with all performance optimization: Measure, measure, measure!

Comments

0

It is architecture specific whether if (!myFlag) myFlag = true; will take more time to execute than the simple myFlag = true; even without any optimization. There are architectures (e.g., https://developer.qualcomm.com/hexagon-processor) where both statements will take only one cycle each to execute.

The only way to figure out on your machine would be by measurement.

In any case myFlag = true will always be faster or have same execution time as if (!myFlag) myFlag = true;

Comments

0

This question gave me headache too so i simply tested it myself with the following code (C#):

        System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
        int i = 0;
        int j = 1;

        time.Start();
        if (i != 0)
            i = 0;
        time.Stop();
        Console.WriteLine("compare + set - {0} ticks", time.ElapsedTicks);

        time.Reset();
        time.Start();
        if (j != 0)
            j = 0;
        time.Stop();
        Console.WriteLine("compare - {0} ticks", time.ElapsedTicks);


        time.Reset();
        time.Start();
        i = 0;
        time.Stop();
        Console.WriteLine("set - {0} ticks", time.ElapsedTicks);

        Console.ReadLine();

result:

compare + set - 1 ticks

compare - 1 ticks

set - 0 ticks

while the time, used to set the value surely isn't zero, it shows that even a single query needed more time than just setting the variable.

1 Comment

While it is nice that you tried testing it..... C# is not C++, not even close in this case as the question is about (potentially) single-instruction execution-times. To get any relevant metrics you first would need to use the same language. And secondly getting meaningful data about such simple testcases is not easy as the compiler is smarter than you AND the times you try to measure need at least hundreds if not thousands of repetitions to measure those tiny differences. (And for the timer you used you should first check its resolution - it is way too coarse to measure this)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.