[Bug c++/26656] New: Optimization flaw on conditionnal set of a bit.
I'm on Gentoo Linux, my the use flags affecting GCC are "fortran" and "nls". I have tried the following with -O2. If I write a piece of code that looks like one of these : example 1 : a = (b == 1 ? 1 : 0); example 2 : a = (b == 1 ? 2 : 0); example 3 : if( b == 1 ) a = 2; else a = 0; The compiler optimizes it by using the sete/setne instruction instead of a potentially slow conditional jump and then doing a bit shift if necessary. However, while code like example 4 : a |= (b == 1 ? 1 : 0) example 5 : if( b == 1 ) a |= 1; is optimized the same way, code like example 4 : a |= (b == 1 ? 2 : 0) example 5 : if( b == 1 ) a |= 2; is not optimized with a sete/setne, a conditional jump is used. Since there is a workaround to make GCC use a sete/setne workaround : t = (b == 1 ? 2 : 0); // or if( b == 1 ) t = 2; else t = 0; a |= 2; I could compare the performance of sete/setne like operations vs conditional jumps on my AMD Ahlon XP 1700+. It turns out that, without -march=athlon-xp, the workaround, using a if() or a ?: as constant speed that is faster than code like example 4 and 5, except when the probability is very close to 1/2. The further from 1/2, the slower, on the extreme, it can be more than 2x slower. At 1/2, the conditional jump is faster, but not by much. For some reason, code like example 4 is slower than code like example 5. With -march=athlon-xp, code like example 5 and the workaround behaves the same, but code like example 4 as a constant time that is however slower than the workaround but faster than most other cases when compiled without -march=athlon-xp. Disassembly shows that it is using a conditional move. -- Summary: Optimization flaw on conditionnal set of a bit. Product: gcc Version: 3.4.5 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dominic dot quiet at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656
[Bug target/26656] Optimization flaw on conditionnal set of a bit.
--- Comment #2 from dominic dot quiet at gmail dot com 2006-03-12 21:23 --- Created an attachment (id=11030) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11030&action=view) Benchmark -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656
[Bug target/26656] Optimization flaw on conditionnal set of a bit.
--- Comment #3 from dominic dot quiet at gmail dot com 2006-03-12 21:31 --- Created an attachment (id=11031) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11031&action=view) My results without -march=athlon-xp -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656
[Bug target/26656] Optimization flaw on conditionnal set of a bit.
--- Comment #4 from dominic dot quiet at gmail dot com 2006-03-12 21:41 --- Created an attachment (id=11032) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11032&action=view) My results with -march=athlon-xp The behavior of the ?: compared to without -march=athlon-xp may be a sign that -march=athlon-xp (I don't know about Intel CPUs and other AMD CPUs) generate slower code for ( ? : 0) operations in general, not just in that case (see my first post in this bug for more details about the generated code), but I don't have time to test it right now. Maybe it's worth opening another bug... -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656
[Bug target/26656] Optimization flaw on conditionnal set of a bit.
--- Comment #6 from dominic dot quiet at gmail dot com 2006-03-12 22:25 --- Created an attachment (id=11033) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11033&action=view) Fixed benchmark I fixed my benchmark. You are right about the condition always being true after 127. I was using signed char... What was I thinking. :-S But I don't see any problem about rand(). I added a display of the frequency of each value, and it seems well balanced. Things are now reversed. When the condition is most likely to be true or most likely to be false, the conditional jump gets faster, instead of slower. But it is still overall slower. -- dominic dot quiet at gmail dot com changed: What|Removed |Added Attachment #11030|0 |1 is obsolete|| Attachment #11031|0 |1 is obsolete|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656
[Bug target/26656] Optimization flaw on conditionnal set of a bit.
--- Comment #7 from dominic dot quiet at gmail dot com 2006-03-12 22:26 --- Created an attachment (id=11034) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11034&action=view) My new results without -marh=athlon-xp -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26656