Path: utzoo!attcan!uunet!husc6!cmcl2!nrl-cmf!ames!pasteur!ucbvax!POSTGRES.BERKELEY.EDU!dillon From: dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) Newsgroups: comp.sys.amiga.tech Subject: Re: Dividing by a power of two (Re: Aztec compiler ineffeciencies) Message-ID: <8811281919.AA17977@postgres.Berkeley.EDU> Date: 28 Nov 88 19:19:44 GMT Sender: daemon@ucbvax.BERKELEY.EDU Lines: 48 :> > As many compiler writers have found in the past and I'm sure many will :> > rediscover in the future, this only works for positive values. Try :> > shifting -1 and you'll get -1 as a result, *not* zero as one would expect. :> I think the problem is that shifting always rounds down, as opposed :> to towards zero, like we expect. So even in cases where you have a :Actually it is much simpler than that. The Lattice 5.0 compiler generates the :3 instructions (sometimes 4) inline to perform the division by 2,4, and 8. :These are the most frequent numbers to occur from analysis of many programs. :Specifically: : x/= 2 : move x,d0 ;unless it was already there : bpl lab ;skip if positive : addq #1,d0 ;adjust for rounding :lab: asr.l #1,d0 ; and do the divide This is also a very good example of what is known as "programmer's experience". No *good* programmer would do constant division by powers of 2 using '/', but would use a shift instead. The programmer, after all, knows exactly what range a particular variable will fall in whether it is unsigned or not, and thus can make optimizations and assumptions the compiler could never match. Take a good look at the example above ... how often do you divide negative numbers by powers of 2? Now, take that probability and ask how often the variable would be unbounded (can take arbitrary values) verses in a known range that can be optimized by some other method. Finally, take into account whether, in the case it IS negative, rounding is desirable. Now you say "But I don't want to worry about it" and "I don't want to have to worry about optimizing it". Bullshit. Either the problem is sooo important that nobody in their right mind would risk a division anyway, or so unimportant that it doesn't matter if it is optimized or not. I wish the compiler writers would take more time to optimize the more frequent cases that occur in tight code rather than these totally useless cases. For example, Lattice does no register tracking and Aztec doesn't do enough. You might say "It is the compiler's job to optimize!", to which I would respond: "Which do you think the compiler can optimize better, a shift, or a divide?". Got it? No matter how good compilers get, certain constructs are more apt to optimization than others due to fewer assumptions having to be made about them, so the 'good' programmer *always* optimizes his code. little goodies might be a boon to the 'ok' programmer, but even with them his program is no where near the theoretical efficiency he could obtain, and what he gains by those (for us) useless cases doesn't help as much as he would like. -Matt