From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5465 invoked by alias); 30 Jan 2012 19:23:01 -0000 Received: (qmail 5455 invoked by uid 22791); 30 Jan 2012 19:23:01 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 30 Jan 2012 19:22:37 +0000 From: "gccbug at jamasaru dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/52056] New: Code optimization sensitive to trivial changes Date: Mon, 30 Jan 2012 20:02:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Keywords: X-Bugzilla-Severity: minor X-Bugzilla-Who: gccbug at jamasaru dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-01/txt/msg03566.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52056 Bug #: 52056 Summary: Code optimization sensitive to trivial changes Classification: Unclassified Product: gcc Version: 4.6.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c AssignedTo: unassigned@gcc.gnu.org ReportedBy: gccbug@jamasaru.com GCC 4.6.1 (also in at least 4.5 and 4.4), 64 bit Ubuntu. The GCC optimizer detects and significantly speeds up some simple inner-loop computations, but small changes to those inner loops can completely change the behavior of the optimizer, losing 50% or more of the code speed. Example code, simplified down from a hash table computation: #include const int UNROLL=8; int main() { // static keyword in next line can trigger optimizer behavior! static unsigned long accum=0; unsigned int sum=0; for (long j=0; j<0x400000000/UNROLL; ++j) for (int unroll=0; unroll>22)); j*=0x6543210123456789; sum+=(unsigned int)(j>>32); } printf("Sum=%d\n", sum); } compile with gcc -O3 test.c -o test The inner loop of shifts, xors, mults, and adds is the core computation. The GCC optimizer is very sensitive to whether the shift above is made with a SIGNED or UNSIGNED long. It is also sensitive to whether the "accum" variable is static or not. Some timings on a i7 980X CPU: Static accum, signed shift: 11.3 seconds Static accum, unsigned shift: 24.3 seconds Local accum, signed shift: 12.1 seconds Local accum, unsigned shift: 14.4 seconds Looking at the assembly -S output, it's clear that the optimizations are valid and effective, with the dramatic speed increase coming from switching over to SSE math. The output is correct in all 4 cases. The only problem is that the optimizer is unable to recognize the same opportunity in all four cases, giving inconsistent performance. This example is simplified down from the inner loops of some of my code involving Monte Carlo simulation, and has a significant affect on runtime. The Intel ICC compiler is significantly slower than GCC in most cases on my code. For this specific example, ICC has an execution time of 14.3 seconds for all 4 cases. That 25% speed advantage of GCC is huge to us when we have 500 machines in a cluster running simulations for days!