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…
