From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,acba876b1e3c9639 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: GNAT Optimization of Constant Expressions Date: Wed, 16 May 2007 23:50:01 -0500 Organization: Jacob's private Usenet server Message-ID: References: <1179355028.624745.258370@q75g2000hsh.googlegroups.com> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: jacob-sparre.dk 1179377279 27987 69.95.181.76 (17 May 2007 04:47:59 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Thu, 17 May 2007 04:47:59 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1807 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1807 Path: g2news1.google.com!news4.google.com!proxad.net!feed.ac-versailles.fr!news.ecp.fr!news.jacob-sparre.dk!pnx.dk!not-for-mail Xref: g2news1.google.com comp.lang.ada:15819 Date: 2007-05-16T23:50:01-05:00 List-Id: "David Smith" wrote in message news:1179355028.624745.258370@q75g2000hsh.googlegroups.com... > In running some benchmarks between Ada, C, and Fortran, I came across > a bizarre situation with GNAT. The same algorithm ran 10x slower in > Ada, so I surmised that the constant math expressions in the code > below were being precomputed by the compiler in C and Fortran, but not > in Ada. To test my hypothesis, I defined the commented-out constants > and replaced the math functions with the appropriate constant. This > worked, and the Ada code was then as fast at the others. The > bizarreness came out when I put the math expressions back in but left > in the constant declarations. The code was still fast! I'm not even > using the constants, but somehow they are helping the compiler > optimize the code. > > In short, when I un-comment the constants, the code is super fast, but > when commented out, the code is slow, even though I never use them. > > Does anyone know why this could be? It doesn't surprise me in the least; I'd expect Janus/Ada to work similarly, in fact. First of all, Sin and the like are regular functions in Ada; they're never built in. I suspect that is different in your typical Fortran compiler. The only thing that the compiler is likely to know about them in Ada is that they are Pure, which means that the compiler can assume that two calls with the same arguments return the same result. As such, the compiler has to do a loop-hoisting optimization in order to pre-evaluate these function calls. I suspect that from your results, Gnat doesn't do such an optimization in this case. That doesn't surprise me, a loop hoist can make the program run slower if the loop is never executed. I don't think we do them at all. I would expect that Gnat does in some circumstances, but for some reason it doesn't notice that the loops are going to execute far more than zero times. Anyway, if you explicitly declare the constants, the situation changes. First of all, these sorts of constants will most likely be implemented much like initialized variables (the value being stored in memory). That's one probably one of the reasons why Gnat doesn't do the optimization (extra memory use). But if you explicitly declare them, there no longer is any extra memory. Moreover, doing so changes the optimization from loop hoisting (which is done in limited circumstances) to common subexpression elimination (which is done whenever possible). [I'm speaking about these optimizations in Janus/Ada here, I have no knowledge of how Gnat/GCC divide up these optimizations; but I'd expect it to be similar.] Since these are Pure function calls, the compiler can replace the later uses by your explicitly declared constants, and thus get your observed speedup. Without the constants, the compiler would have to effectively declare them itself, and there are a number of reasons that the compiler might not choose to do that (as previously mentioned). In any case, the best rule for a compiler optimizer is to implement what was written if you cannot be sure that the optimization will be faster/smaller. So I'm not surprised. After all, your original code is written to make a bunch of very expensive calls ("Sin(0.5)", for instance) many times. Expecting the compiler to remove those calls is asking a lot; it is much better to avoid making extra calls with appropriate constant declarations. (I'd have that advice for any language; why force the optimizer to work hard and possibly fail??) Randy.