difference in local and instance variable results...

I have this code:

Code listing: A


            double sum = 0.0;

            @Override
            public void run()
            {
               int depth = 250;

               for (int a = 0; a < depth; a++)
                  for (int b = a + 1; b < depth; b++)
                     for (int c = b + 1; c < depth; c++)
                        for (int d = c + 1; d < depth; d++)
                           sum += Math.sqrt(a + b + c + d);

               System.out.println("sum=" + sum);
            }

Output


sum=3.5056001420551696E9
sum=3.5056001420551696E9
sum=3.5056001420551696E9
sum=3.5056001420551696E9

Code listing: B


            @Override
            public void run()
            {
               int depth = 250;

               double sum = 0.0;
               for (int a = 0; a < depth; a++)
                  for (int b = a + 1; b < depth; b++)
                     for (int c = b + 1; c < depth; c++)
                        for (int d = c + 1; d < depth; d++)
                           sum += Math.sqrt(a + b + c + d);

               System.out.println("sum=" + sum);
            }

Output


sum=3.5056001420551696E9
sum=2.789092624904878E9
sum=2.8371074309628153E9
sum=2.806383173404868E9

Note: these are 4 threads concurrently running on a quad-core machine (all in their own Runnable instance, ofcourse).


      for (int i = 0; i < 4; i++)
      {
         Runnable task = new Runnable()
         {
             // impl
         };

         new Thread(task).start();
      }

As you can see, the only difference is that the ‘sum’ variable has another scope (local vs. instance)

I realize memory-access works different for them, and the bytecode is very different, but… I thought either both should be deterministic, or both should be unpredictable due to floatingpoint being slightly non-deterministic in x86 / x64…

Seems to work fine for me (Core 2 Quad, Q6600),

All 4 results for both tests give “sum=3.5056001420551696E9” everytime.

(Using JRE 1.6.0_10-ea)

That worries me… this is a brand new PC… (btw, also a Q6600)

Hm… I ran a Memtest, and everything was fine… I ran the 32-bit VM (jre160_04) on a 64-bit OS (Vista) … I might do some other tests later today.

Ha! The 64bit version of JRE160_04 produced ‘stable’ results!

So… what happened? :-\

I also tried:


        double sum = 0.0f;
               for (int a = 0; a < depth; a++)
                  for (int b = a + 1; b < depth; b++)
                     for (int c = b + 1; c < depth; c++)
                        for (int d = c + 1; d < depth; d++)
                           sum += (a+b+c+d)/123456789.0;//Math.sqrt(a + b + c + d);


sum=85.20330685445509 <---------------------------- WTF
sum=640.9012427900386
sum=621.0207516557817
sum=640.9012427900386
sum=640.9012427900386
sum=640.9012427900386
sum=629.505959999343
sum=640.9012427900386
sum=640.9012427900386
sum=640.9012427900386

WAY worse than rounding errors!!

This is: JRE160_04 32bit, 64bit Vista, Q6600

JRE160_04 64bit works fine! (all: sum=640.9012427900386)

don’t scare me like that riven!

I am sleepy, since I’m having trouble sleeping. But that just can’t be something I’ve said: unless: I installed vista tested stuff AND magicly got back to xp whilst sleep walking seemed pretty impossible.

The idea that you would have hit edit instead of quote saved my insanity. :stuck_out_tongue:

:o

I think my parallel universe just got out of sync! Might explain the other anomalies…

I can’t check this stuff right now on my machine, but I’m curious - are the inconsistent results at least consistent from run to run, or do they vary as well?

hmm, my test was with 32bit XP.

I havae 32bit Vista… but don’t want to downgrade just to test this :-\

Highly random! But tends to stabilize the longer it runs. :o

Apart from stating the obvious by saying that downgrading is the future, I can only wait for people here with x64 Vista running a x86 JRE and give it a whirl…