helios
you need to show that thermodynamics will cause the threads to go significantly out of sync from each other |
Ok. That will be difficult and an expensive experiment. But probably it will be done.
the current element of the sequence has very little correlation with the previous element. |
I agree with you. That's why it is required to answer these questions in order to predict the numbers:
When did thread 0 start to change the output? Which value had the possible output at that moment? Which was the state of thread 1? Which was the exact speed of thread 0 and thread 1? Which was the exact thermodynamic entropy of CPU 0 and CPU 1? Which was the exact conductance of each CPU circuit? Which was the exact frequency of computer's oscillators?
Instead of arguing the philosophy of quantum mechanics with me you could be fixing the algorithm, which I have indirectly explained how to do in my previous post. |
Since you wrote that post I've been analyzing the code, trying to improve it. And used all options, that I could. This is the best way I actually have to generate true random numbers through CPU time jitter and data races.
From #3 we know that loads and stores will be atomic. You will never get or save a value in a half-updated state. |
Thank you very much helios. I didn't know that. You taught me something new! :D
You're reading the results as fast as the thread is able to, independently of any timings external to the CPU clock.
The paper on jitter obtained entropy from the variation in nanoseconds of the speed of checking the time in nanoseconds. You're not doing anything that's in any way similar to that. |
I agree with you. The version for more than two CPUs reads the results as fast as the thread is able to. The version for one CPU confronts the CPU speed with the real time clock.
Code analysis
This is an extract of the binary dump compiled for x86_64 and refers to:
void inline thr(Num const num)
1 2 3 4 5 6 7 8 9 10 11 12
|
mov (out),%rdx #read the value of out
mov (tmp),%rcx #read the value of tmp
lea 0x0(,%rdx,8),%rax #step 1: multiply out*7
sub %rdx,%rax #step 2: multiply out*7
add %rcx,%rax #add the value of tmp to out
mov %rax,(out) #save the result (out=out*7+tmp)
mov (tmp),%rdx #read the value of tmp
lea 0x0(,%rdx,8),%rax #step 1: multiply tmp*7
sub %rdx,%rax #step 2: multiply tmp*7
add %rsi,%rax #add the value of num
mov %rax,(tmp) #save the result (tmp=tmp*7+num)
jmp beginning #do it again
|
Defining a clock as a device with a rate of change through the time: A data race is the result of confronting two clocks and CPU time jitter is the confrontation of both clocks.
The CPU speeds change slightly due to their physical entropy caused by the execution of a single instruction, due to their energetic inefficiency.
When the entropy level is enough to activate the heatsink fan, then this entropy will be exchanged faster with the environment.
When executing two threads exactly at the same time in two different CPUs and when
tmp=out=0
, there can happen two cases:
Thread 0
1 2 3 4 5 6 7 8 9 10 11
|
mov (out),%rdx #rdx=0
mov (tmp),%rcx #rcx=0
lea 0x0(,%rdx,8),%rax #rax=0
sub %rdx,%rax #rax=0
add %rcx,%rax #rax=0
mov %rax,(out) #out=0
mov (tmp),%rdx #rdx=0
lea 0x0(,%rdx,8),%rax #rax=0
sub %rdx,%rax #rax=0
add %rsi,%rax #rax=0
mov %rax,(tmp) #tmp=0
|
Thread 1
1 2 3 4 5 6 7 8 9 10 11
|
mov (out),%rdx #rdx=0
mov (tmp),%rcx #rcx=0
lea 0x0(,%rdx,8),%rax #rax=0
sub %rdx,%rax #rax=0
add %rcx,%rax #rax=0
mov %rax,(out) #out=0
mov (tmp),%rdx #rdx=0
lea 0x0(,%rdx,8),%rax #rax=0
sub %rdx,%rax #rax=0
add %rsi,%rax #rax=1
mov %rax,(tmp) #tmp=1
|
Case #1
The relative speed between the two clocks is different than zero.
CPU 0 executed the above instructions at a speed of: 2.1111111 GHz
CPU 1 executed the above instructions at a speed of: 2.0999999 GHz
Relative speed between the two clocks: 0,0111112 GHz
CPU 0 were faster and CPU 1 where slower.
tmp=0
was written before
tmp=1
.
Hence the final result is:
tmp=1
Case #2
Relative speed between the two clocks is exactly zero.
CPU 0 executed the above instructions at a speed of: 2.1111111 GHz
CPU 1 executed the above instructions at a speed of: 2.1111111 GHz
Relative speed between the two clocks: 0 GHz
CPU 0 and CPU 1 wrote a different value at the same time, what put the last bit of
tmp
on a superposition state.
It is 1 and 0 at the same time. This superposition may live for one planck time or until its value is read by thread 0, thread 1 or thread 2.
Thread 2
1 2
|
while(true)
cout.write((char*)&out,sizeof(out));
|
It is also possible, that gravitational waves caused by the flow of energy inside the CPUs produce small time dilations.
Desynchronization
1 2 3 4 5 6 7 8 9 10 11
|
mov (out),%rdx #out may be changed by the other thread
mov (tmp),%rcx #tmp may be changed by the other thread
lea 0x0(,%rdx,8),%rax
sub %rdx,%rax
add %rcx,%rax
mov %rax,(out) #out may never be read
mov (tmp),%rdx #tmp may be changed by the other thread
lea 0x0(,%rdx,8),%rax
sub %rdx,%rax
add %rsi,%rax
mov %rax,(tmp) #tmp may never be read
|