I need to find in an image if a pixel has the maximum value compared to the 8 pixels around it.
I am not sure what is the most optimal way, so my idea is to use the if statement like this:
if(pixel > pixel1 && pixel > pixel2 && pixel > pixel3 && ... && pixel> pixel8)
My question is the following: if it found that for instance pixel is not bigger than pixel1, will it still check the rest of the statement or since it's only ANDs, it will already discard the instruction and go further?
And if the answer is the first one, that would make it very computationally heavy to check each pixel all the time, can somebody give me a hint as how to approach more efficiently this simple problem?
This is called Short Circuit Evaluation.
the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression
Since the condition is &&, it will NOT check further if it gets a false in any of the conditions.
Similarly if the condition were ||, it would stop checking once it finds a true.
Btw, I am not absolutely certain of the precedence rules, and because of that I would surround each condition in parentheses just to be safe.
if((pixel > pixel1) && (pixel > pixel2) && ...
Edit: Operator precedence rules seem to indicate that the parentheses in this case are unnecessary.
No, it won't check the rest of the statements. C++ "short-circuits" conditional statements, ignoring the second operand to an && if the first is false (and ignoring the second operand to a || if the second is true).
The operators && and || are so-called 'short circuit operators' in C++ (and in most other languages as well). This means that evaluation will stop as soon as the result can be determined. For &&, this means that evaluation of other terms will stop if one term is false, because then the answer is false, independent of the other terms. Conversely, for || this means that evaluation of other terms will stop if one term is true.
See also this link.
Think of it not as a series but a grouping of expressions so && has just a left and right side, and is left-side associative.
If the left hand side evaluates to false it is guaranteed by the standard not to evaluate what is on the right hand side. The right hand side might even contain an access violation (and often does), e.g. checking if a pointer is non-null on the left side, then dereferencing it on the right.
Your operation is O(N) at worst. If you do this once, it is the optimal way, if you are going to do this a lot, you'd be better off finding the max value of your pixels then just checking against that one.
There is "short-circuit" in C++ that means when first condition satisfies if then the second condition will not checked.
For example if pixel > pixel1 results false the following conditions will be ignored.
I refer you to this "Short circuit evaluation"
While short circuit evaluation has been explained in other answers, it's worth pointing out that a comparison of two pixels may not be completely trivial. For example, you may wish to add red, green and blue pixel values after multiplying them by a weighting factor (as the human eye is more sensitive to some colours than others)... in that case, if you don't preserve the overall pixel value inside the object being compared (thereby using more memory both for that value and to somehow track when it's invalidated, + CPU time to check & regenerate it when necessary), then you'll have to perform this redundant calculation during every one of those comparisons. To avoid this, you might - for example - add a "get_brightness()" function that returns a user-defined type that can be compared efficiently with each of the other pixels.
Related
I'm reading a book about rendering 3d graphics and the author sometimes uses epsilon and sometimes doesn't.
Notice the if at the beginning using epsilon and the other ifs that don't.
What's the logic behind this? I can see he avoids any chance for division by zero but when not using epsilon in the function there's still a chance it will return a value that will make the outer code to divide by zero.
Book is Real-Time Rendering 3rd Edition, by the way.
The first statement, if(|f| > ϵ) is just checking to make sure f is significantly different from 0. It's important to do that in that specific spot in the code because the next two statements divide by f.
The other statements don't need to do that, so they don't need to use ϵ.
For example,
if(t1 > t2) swap(t1, t2);
is a self-contained statement that compares two numbers to each other and swaps them if the wrong one is greater. Since it's not comparing to see if a value is close to 0, there's no need to use ϵ.
If the value that is returned from this block of code can make the calling code divide by zero, that should be handled in the calling code.
I'm currently dissecting through the ol' Doom engine source code, and came across an interesting line:
counter = (++counter)&(MAX_VALUE-1);
Looks like a way to increment a counter without going over a certain number, but I have a tricky time doing bitwise operations in my head so I whipped up a quick console project to try this out, and lo and behold, it works beautifully. I deduce the above way is more efficient than an if() statement, especially if the code is executed rapidly, for example, within a loop, where performance within a real-time game is crucial. What I'm trying to figure out is the order of operations the compiler uses to execute this line. If the increment '++' operator is placed after the 'counter', it will always remain zero. It only works if the increment is used as a prefix ("++counter"), but even still, if I write it out with pen and paper, I get the arbitrary result of the bitwise AND operation, not a counter that increments. It seems the bitwise operation is calculated, and THEN the increment is performed, but I'm stumped figuring out why, any ideas?
While the parentheses have higher precedence than operator ++ or bitwise AND (operator &), there are no defined sequence points in your right-hand side. So your code exhibits undefined behavior.
If you remove the operator++ what this is intending to do is
(counter + 1)&(MAX_VALUE-1);
If you consider MAX_VALUE to be 32 then MAX_VALUE-1 in binary is
11111
So if you have a larger value than that and use & any bits left of bit 5 (from the right) will be cleared
0000011111 // assume this is MAX_VALUE - 1
1100110110 // assume this is counter + 1
__________
0000010110
The result would be true if any of the bits less than or equal to MAX_VALUE - 1 were 1.
The formula
counter = (++counter)&(MAX_VALUE-1);
has undefined behaviour, see CoryKramer's answer.
The formula
counter = (counter + 1)&(MAX_VALUE - 1);
works only for MAX_VALUEs that are equal to a power of 2. Only then the value MAX_VALUE - 1 has this form in binary:
000...000111...111
When such a value is used in a AND operation, it "truncates" the higher bits of the other value, and has the effect of wrapping around when the other value reaches MAX_VALUE.
I think the normal modulo operation is just as fast on modern hardware, and does not have the restriction mentionend above:
counter = (counter + 1)%MAX_VALUE;
The statement after decreases has to get strictly smaller in each loop and always be non-zero. But does it have to reach 0? Does it have to get smaller by one?
As stated in the JML documentation, decreases (you can also write decreasing) means that an int or long expression with that specifier "must be no less than 0 when the loop is executing, and must decrease by at least one (1) each time around the loop."
So it may or may not reach 0, but can't get smaller than that. Also, it has to get smaller by at least, but not necessarily exactly one. Note the example in the documentation for a more precise explanation.
I can't really find any answer in the Modelica specification so ill ask you guys. The specification states that
A tool is free to solve equations, reorder expressions and to not evaluate expressions if their values do not influence the result (e.g. short-circuit evaluation of Boolean expressions). If-statements and if-expressions guarantee that their clauses are only evaluated if the appropriate condition is true, but relational operators generating state or time events will during continuous integration have the value from the most recent event.
If a numeric operation overflows the result is undefined. For literals it is recommended to automatically convert the number to another type with greater precision.
Now, I wonder, can the tool choose to evaluate an expression several time in an integrator step? For example (probably not an valid example, just to give you guys an idea of what I was wondering :) )
Real x;
equation
der(x) = -t;
Modelica.Utilities.Streams.print(String(time));
This will print the same time for several times, so I figured that there is some kind of iteration going on. But I would really like to have it confirmed by some source.
That is normal.
Variable step size solvers (like dassl) can go back
and forth in time to find the direction of the curve.
Also, if you have events more values can be generated
at the same time.
If you want to print time or values just at exact time instants you need when equations:
when sample(0, 1) then
Modelica.Utilities.Streams.print(String(time));
end when;
Read more in the Modelica Spec about sample.
Is also possible to use fixed step size solvers like Euler or so.
To check an int within range [1, ∞) or not, I can use the following ways (use #1, #2 a lot):
if (a>=1)
if (a>0)
if (a>1 || a==1)
if (a==1 || a>1)
Is there any difference that I should pay attention to among the four versions?
Functionally there is no difference between the 4 ways you listed. This is mainly an issue of style. I would venture that #1 and #2 are the most common forms though, if I saw #3 or #4 on a code review I would suggest a change.
Perf wise I suppose it is possible that some compiler out there optimizes one better than the other. But I really doubt it. At best it would be a micro-optimization and nothing I would ever base my coding style on without direct profiler input
I don't really see why you would use 3 or 4. Apart from being longer to type, they will generate more code. Since in a or condition the second check is skipped if the first is true, there shouldn't be a performance hit except for version 4 if value is not 1 often(of course hardware with branch prediction will mostly negate that).
1. if (a>=1)
2. if (a>0)
3. if (a>1 || a==1)
4. if (a==1 || a>1)
On x86, options 1 and 2 produce a cmp instruction. This will set various registers. The cmp is then followed by a condition branch/jump based on registers. For the first, it emits bge, for the second it emits bgt.
Option 3 and 4 - in theory - require two cmps and two branches, but chances are the compiler will simply optimize them to be the same as 1.
You should generally choose whichever (a) follows the conventions in the code you are working on (b) use whichever most clearly expresses the algorithm you are implementing.
There are times when explicitly writing "if a is equal to one, or it has a value greater than 1", and in those times you should write if (a == 1 || a > 1). But if you are just checking that a has a positive, non-zero, integer value, you should write if (a > 0), since that is what that says.
If you find that such a case is a part of a performance bottleneck, you should inspect the assembly instructions and adjust accordingly - e.g. if you find you have two cmps and branches, then write the code to use one compare and one branch.
Nope! They all are the same for an int. However, I would prefer to use if (a>0).