>don't worry dude, the compiler will optimize it
So how come the compiler won't compile all these to the same thing?
Don't worry dude, the compiler will optimize it
Other urls found in this thread:
different names
You should really use gcc.godbolt.org
The first 5 are actually identical, so are the second two. I don't know why would you expect for them all to be identical since the C code is different.
the only situation you should worry about being smarter than the compiler is if you're working on embedded with extremely tight requirements and even then you may as well just write it directly in asm,
>So how come the compiler won't compile all these to the same thing?
Optimizations are just transformations from one program to a different one.
If the compiler does this, he needs to prove that both programs are equivalent. That is hard to do automatically in many cases.
Because bitshift does not equal division by two in every case (unsafe optimization);
and the remaining things are semantically different.
The trick to writing optimized code is recognizing when you can use faster operations and achieve same results in cases where it is unclear on a strictly-theoretical level.
What I mean is:
you use knowledge about code's *purpose* (which is unavailable to the compiler) to force otherwise unsafe optimizations through.
Still, the "don't worry dude" approach is correct.
If you worry about optimization, in 99% cases it's wrong to do.
Do the same with unsigned types, or fuck around with -fwrapv.
The first 5 are identical, optimized to cmovge (which is slightly slower than bithack in many cases) since the optimization is trivial. The last second 2 are not identical, one has xor, mov, xor, the other one has sub, lea. The averages are of course identical, x/(2^n) to x >> n is another trivial optimization.
No, if the compiler does retarded shit like this then I have no way of telling how well it will actually optimize when it does matter.
It's trivial in the average ones, it knows that x == y already. And this is a well known pattern, there could be special code to detect common algorithms for doing stuff and replacing them (within reason)
But division by two is optimized to shift, what's your point here? It misses a lot of stuff that's trivial to detect, it would be easy to check the different branches it can take. Also, cmovge (first 5) is slower than max_bithack_xor. What you "should" do is completely unimportant, the issue is that if the compiler fails optimizations like these it sure misses a lot more.
Huh? Unsigned overflow is undefined.
>the issue is that if the compiler fails optimizations like these it sure misses a lot more.
So you want your compiler to always give OPTIMAL results? What you are saying is impossible.
You are claiming compiler should be able to optimize every program that has exactly same semantics to exactly same machine code.
Trouble is: if we assume this were possible, we could determine if two programs are the same by compiling them and comparing code.
And if we could do that, we have a straightforward proof that NP = co-NP and henceforth P = NP and cryptography is doomed.
(Halting problem becomes decidable)
Optimization is meant to lighten the burden of coding well off programmers; it's *not* meant to turn every program optimal.
even if you use fwrapv or unsigned ints, the result is going to be different if x+y overflows, also it's technically undefined behavior anyway so the compiler is not to be expected to optimize anything
if it's true that getting rid of the cmov results in less cycles used (haven't tested), then maybe gcc is optimizing for cycle count. for whatever reason it appears that it's ignoring that x ^ y ^ y = x in this case, even though it picks it up in simpler scenarios.
curiously, clang actually optimizes the bithack_arithmetic one into the same three instructions as the first 5
>No, if the compiler does retarded shit like this then I have no way of telling how well it will actually optimize when it does matter.... if the compiler fails optimizations like these it sure misses a lot more.
wtf, are you daft? why do you think c compilers have so many optimization options? there is no "perfect" way to optimize any high-level code, if you really want control over what you're doing then hand-write the assembly yourself
>And if we could do that, we have a straightforward proof that NP = co-NP and henceforth P = NP and cryptography is doomed.
(Halting problem becomes decidable)
How so? Just because the Halting Problem becomes decidable doesn't make it belong in NP.
>any and every co-r.e. becomes r.e. because it can use "magical compiler optimize trick" (which is recursive as established), to test for program semantics
>if something is both co-r.e. and r.e. it is recursive
>thus all recursively enumerable and co-recursively enumerable functions are now magically recursive
Now add the following facts:
>compilers operate in P-time
>comparing two sets of machine code operates in P-time
and you get P = NP.
Thing is, we know for a fact that there are r.e. functions that are not recursive, which stands in contradiction with compilers being able to produce optimal code (otherwise all r.e. functions would be recursive - false).
>compilers operate in P-time
Who says my magic compiler would operate in polynomial time?
>NP = co-NP and henceforth P = NP
Doesn't follow.
>Halting problem becomes decidable
No.
Then it doesn't.
co-r.e. = r.e. = recursive already carries more severe consequences than P = NP.
>we can constructs a reduction from any co-r.e. function to a r.e. function (using given recursive optimize() function)
>halting problem doesn't become decidable
??
>co-r.e. = r.e. = recursive already carries more severe consequences than P = NP.
Well yeah. I was just confused about your talk about run-time complexity.
What editor is this? It looks so baller.
I was just guessing that if we can compute the uncomputable, then we might be able to compute difficult problems quickly.
If I had to gamble I'd say there's a formal proof to be had, but I admit I haven't given it much thought and may be completely wrong.
vim
No, it can replace x with y in max_else_if_eq_avg and max_else_if_eq_avg_shift, then it gets (x+x)/2, which it will replace with 2x/2 and then constant propagate to x/2. Only the first part is missing. And it's definitely not "solve the halting problem" tier to have optimal asm implementations of common algorithms.
But it misses some very apparent optimizations, the bithack isn't the real issue. Clang has a more sane approach then, since it's subarch dependent and cmovge is the "canonical" approach. If you run the entire program through clang, does it optimize max_else_if_eq_avg and max_else_if_eq_avg_shift too?
vim + base3024
So what was actually fastest
Just skip the middle man and program everything in x86 assembly. Problem solved.
/thread
see