Question on execution of unlikely()
So unlikely is a nice way to cut down on how the kernel executes certain tests that you doubt will fail.
For instance I kmalloc a piece of memory and it's unlikely I still have a null pointer- Code:
s_ptr = kmalloc(sizeof(struct some_struct), GFP_KERNEL) Code:
if(unlikely(!(s_ptr = kmalloc(sizeof(struct some_struct), GFP_KERNEL))) |
A discussion about these conditional branching mechanisms is interesting. I have read many of the macro's to unravel 'what the intention is'. I still don't see it very clearly. I saw a double explanation point in front of a conditional. "!!(cond)" I'm not sure of this usage, but curious.
|
Quote:
You'll have to measure. |
Quote:
|
Quote:
The test itself needs to be executed regardless of the low probability of a true result. But the compiler could change the code that would be executed after true is seen to optimize the typical flow: 1) The simple and obvious optimization is to put that code out of line from the main flow, hopefully in a different cache line. So the code that isn't normally executed won't be read into the cache and won't push more useful code out of the cache. 2) I don't think GCC does this (but I think it ought to): Within sections of code whose execution is unlikely, regardless of any overall optimization setting biasing in favor of speed over space, there should be a local optimization of space over speed. Simply put, compile the unlikely to be executed code into as small binary as possible to further minimize its impact on the cache, on virtual memory paging, etc. Quote:
Burying the assignment inside the test makes the code harder to read, harder to maintain and harder to debug. If there is any useful information handed to the optimizer by burying the assignment that way, I expect the optimizer would have found the same information by itself from the more readable form. |
That makes sense.
The compiler has the possibility to 'not branch' for the 'likely' case, and then to 'branch' for the 'unlikely' case. For the 'likely' case, no branch is taken and the following instructions have probably already been fetched by the bus processor look-ahead/prefetch. I think the prefetch advantage is in addition to the cache optimization John discussed. Very nice idea, even if the compiler hasn't taken advantage of it yet. Quote:
Maybe "(cond != 0)" might be more concise. |
Quote:
However, I was mostly using the assignment as an example, such cases might exist where I think burying it is more readable. Something quick that comes to mind is if(isalpha(c)). I feel like the readability of that better describes the operation rather than assigning the result of isalpha() to a variable then testing the variable. Either way, an interesting discussion so far on optimizing. |
Quote:
I objected to unnecessarily burying the assignment operator inside the condition. I also do bury a lot of assignment operators inside conditions, but only when the flow of code would be broken up if you didn't, for example: Code:
if ( pnt == 0 Then I try to minimize the inherent unreadability by making very clear the '=' wasn't a typo for '==' and with a line break to highlight the extra operation. |
Quote:
|
Quote:
I tend to think about the optimizer reaction first. After I decide a choice will make no difference to the optimizer, then I try to arrange it for maximum maintainability. |
All times are GMT -5. The time now is 06:29 PM. |