Xref: utzoo comp.lang.smalltalk:3072 comp.object:3691 Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!uunet!abvax!iccgcc.decnet.ab.com!klimas From: klimas@iccgcc.decnet.ab.com Newsgroups: comp.lang.smalltalk,comp.object Subject: Re: Integer / Float arithmetic in ST80 (Some benchmarks) Message-ID: <1991Jun11.175540.4836@iccgcc.decnet.ab.com> Date: 11 Jun 91 22:55:40 GMT References: <1991Jun5.185120.8104@bqnes74.bnr.ca> Lines: 153 In article <1991Jun5.185120.8104@bqnes74.bnr.ca>, CWatts@BNR.CA (Carl Watts) writes: Because of some sort of problem with Carl's mail reader I have reformatted his posting and inserted a few observations of my own on a subject that has now gotten far away from my original short posting about the potential suitability of Smalltalk for numerical computations. I was not convinced that this thread was worth much net bandwidth and hence I was trying to keep it offline however since Carl brought this to the public forum with so many issues, I thought that I would try to answer what little I knew about the subject. > In regards to the "Re: Integer / Float arithmetic in ST80 (Some benchmarks)" > message I posted a while ago, "Ed Klimas" sent me a response through normal > mail. Because the message and my response are of general userfulness to > Smalltalkers, I'll post my answer here (hope you don't mind Ed?) I don't, but all of our mail readers do ! > > You said in your message "I also don't see how the execution is limited to > 1250 times, an interval of 1 to 2499 IS presented to the block under all of > the SMalltalks that I tested." > > If you execute the following in Smalltalk-80 v2.5 (or earlier probably) > (it won't execute at all in Smalltalk-80 v4.0): > > | c | c := 0. > 1 to: 2499 by: 1 do: [:a | > a := (a*a) sqrt ln exp arcTan tan + 1. > c := c + 1] > you will see that the final value of "c" is 1251 NOT 2500. This shows the > loop only executed half the number of times it was intended to. Under Digitalk's Smalltalk this does execute properly with C having the final correct value of 2499 > > I'm not sure also that readers of the above code would realize (as my friend > Joe May didn't) that: > a := (a*a) sqrt ln exp arcTan tan + 1 > is the same as (given precise arithmetic): > a := a + 1 > This is important because it is easier to see the problem with: > 1 to: 2499 by: 1 do: [:a | a := a + 1] > since you don't get thrown off by the trig functions. > > The Smalltalk-80 v2.5 compiler compiles the to:by:do: message inline. This > message doesn't actually get sent, instead the code for it is compiled right > into the method that uses it. The comment for the method Integer>to:by:do: > mentions this. > > This would be fine if it weren't for the fact that a certain optimization is > done by the compiler when it does this. This optimization has a bug in it > in that it allows assignment to the blocks local variables ("a" in your case) > to have an effect on the next invocation of the block. > > This means your "a := ... + 1" DOES IN FACT increment "a" for the next > invocation of the loop. But the to:by:do:'s job is also to increment the > parameter to the block each time through the loop. So because of this > inline bug, the "a" gets incremented TWICE through the loop. This is why it > only executes 1250 times instead of 2500 times. Interesting theory, but how does it explain the fact that the answers come out correctly? > Anway, even in other Smalltalk's which don't have this bug, the Savage Test > code you used is still improperly formed. In these Smalltalk's the "by: 1" > part, the "a:=" part, and the "+1" part of the loop shouldn't be there. > The "by: 1" is unnecessary, the "a :=" is meaningless (or illegal), and > the "+1" is improper since the reason you are using to:by:do: is because it > increments the parameter to the block. A rebuttal on this one! The by: 1 IS necessary to avoid a potential bug in some of the older Digitalk virtual machines (they also razzle dazzled themselves with some optimizations ). There is nothing in the Blue Book or elsewhere that I am familiar with that says that the a:= in a block is an illegal expression, although PPLace has made changes to ST-80's handling of blocks now. I suspect that this probably would cause significant grief from Digitalk's much larger customer base if they also tried to follow PPlace on this as they might have to change their existing code. > The other code you gave (if you want to answer the final value of "a") is > also wrong: > | a | > 1 to: 2499 by: 1 do: [:a| a:= (a*a) sqrt ln exp arcTan tan +1] > ^a > > In a properly functioning Smalltalk this either: a) wouldn't execute at all > because its illegal to assign to a parameter to a block or: b) would answer > "nil" since the "a" inside the loop is a different "a" from the one outside > the loop. Depends which dialect one considers properly functioning ! It functions just nicely on all of the Digitalk Smalltalk's and I don't believe that it was illegal to assign a parameter inside a block when the Blue Book was written. However to acknowledge that ST-80 may complain about the scoping, one can get identical results with | b | 1 to: 2499 by: 1 do: [:a| b:= (a*a) sqrt ln exp arcTan tan + 1] ^b > In some Smalltalk's this expression would happen to work ONLY because of > TWO known "bugs" in the these Smalltalks. The first is the aforementioned > bug in the Compiler's inlineing of the to:by:do: statement. The second bug > is the fact that some Smalltalk's (like older Smalltalk-80's) used method > temp vars for block temp vars. In any properly functioning Smalltalk, that > expression would never work right. What do we do if I tell you that Digitalk's Smalltalk does do it, tell them to make it so it doesn't? > You definitely want: > | a | > a := 1. > 2499 timesRepeat: [a := (a*a) sqrt ln exp arcTan tan + 1] My copy of ST-80 for Windows won't handle this expression but Digitalk does! Give me an expression that you've checked first and I'll be glad to rerun it on the other dialects. > > I found it very interesting that you reported that Smalltalk/V answered the > precise answer "2500" for the final value of "a" with the code you gave > above. This shows that either Smalltalk/V is using incredibly precise trig > arithmetic OR that you got the answer "2500" only because of the > aforementioned bugs in the Smalltalk implementation. Only because of these > bugs could your expression happen to have given you the right answer. Not so. Digitalk's answers are exact! As I mentioned in my private email to you on this subject, I verified that there was no monkey business going on by eliminating one of the transcendental functions that would have rebalanced the answer. As expected the answer changes, with changes to the equation. As far as I can tell there is no reason to be suspect of the answers that Digitalk's Smalltalk produces. > > I suspect if you redo your benchmark test using my version of this Savage > Benchmark, you will find: > > a) Smalltalk/V does not have incredibly precise trig arithmetic, it was > just a bizarre coincidence that bugs in your expression made use of bugs > in the Smalltalk to give you the impression that it did. This theory has been disproven using the fact that your version of the benchmark on Digitalk's Smalltalk also gives the correct answer exactly. > > b) The times you gave for Smalltalk-80 v2.5 were off by about 50% because > the loop only executed half the expected number of times. I don't believe this is true because the answer under ST-80 comes out very closely to the correct one with just a little residue (it was 2500.11). One thing to note is that when doing the actual timing tests, I did not display the answer, because it was not germain to what was being measured. > > Please get back to us about Smalltalk/V's precision. I would be very > interested to find out how Smalltalk/V fares in precision to Smalltalk-80 > for a properly formulated expression of this benchmark. So far /V looks right on, but give me your properly formulated expression via email (after you fix your mail reader ) and I'll be happy to discuss the results offline, further.