Elementary cellular automaton/Random number generator: Difference between revisions

Content added Content deleted
(added assembler optimized pascal version)
m (→‎{{header|Pascal}}: make ist comparable to D two million tests)
Line 308: Line 308:
=={{header|Pascal}}==
=={{header|Pascal}}==
{{Works with|Free Pascal}}
{{Works with|Free Pascal}}
Use 32-Bit assembler for speed like in Delphi-forum years ago.Sometimes it helps.<BR>Speedtest only for Next_State_Rule_30, no extraction of Bits like in D [http://rosettacode.org/wiki/Elementary_cellular_automaton/Random_Number_Generator#D] with 8x2E6 calls.
Use 32-Bit assembler for speed.
<lang pascal>Program Rule30;
<lang pascal>Program Rule30;
//https://www.entwickler-ecke.de/viewtopic.php?t=111812
//http://en.wikipedia.org/wiki/Next_State_Rule_30;
//http://en.wikipedia.org/wiki/Next_State_Rule_30;
//http://mathworld.wolfram.com/Rule30.html
//http://mathworld.wolfram.com/Rule30.html
//https://www.entwickler-ecke.de/viewtopic.php?t=111812
{$IFDEF FPC}
{$IFDEF FPC}
{$Mode Delphi}
{$Mode Delphi}
Line 324: Line 324:
SysUtils;
SysUtils;
const
const
maxRounds = 100*1000*1000;
maxRounds = 2*1000*1000;
rounds = 10;
rounds = 10;


Line 330: Line 330:


const
const
RULE30_BITSIZE = 64;
RULE30_BITSIZE = 8*8;


SizeOfRegister = SizeOf(NativeUint);
SizeOfRegister = SizeOf(NativeUint);
Line 355: Line 355:
Rule30_State[i] := 0;
Rule30_State[i] := 0;
end;
end;



function BinStr(Zahl: Uint32): String;
function BinStr(Zahl: Uint32): String;
Line 370: Line 369:
end;
end;


procedure Ausgabe;
procedure Out_Rule30_State;
var
var
i : integer;
i : integer;
Line 414: Line 413:
RCL ECX,1 // shift MSB into LSB
RCL ECX,1 // shift MSB into LSB


BT EDI,0 // das LSB of next
BT EDI,0 // LSB of next
MOV EDX,EAX
MOV EDX,EAX
RCR EDX,1 // shift LSB into MSB
RCR EDX,1 // shift LSB into MSB
Line 422: Line 421:
MOV Dword Ptr [EBX],ECX; // save
MOV Dword Ptr [EBX],ECX; // save
ADD EBX,SizeOfRegister // next Pos
ADD EBX,SizeOfRegister // next Pos
cmp EBX,ESI
CMP EBX,ESI // MOV does not change flags
MOV ECX,EAX // running to previous
MOV ECX,EAX // running to previous
MOV EAX,EDI // next to running
MOV EAX,EDI // next to running
Line 428: Line 427:


POP EDI;POP ESI;POP EBX;
POP EDI;POP ESI;POP EBX;
end ['EBX','ESI','EDI'];
end;// ['EBX','ESI','EDI'];


procedure Speedtest;
procedure Speedtest;
var
var
i: integer;
T1,T0 : TDateTime;
T1,T0 : TDateTime;
i,j,b: NativeInt;
Begin
Begin
writeln('Speedtest for statesize of ',RULE30_BITSIZE,' bits');
writeln('Speedtest for statesize of ',RULE30_BITSIZE,' bits');
InitRule30_State;
InitRule30_State;
T0 := time;
T0 := time;
For i := maxRounds-1 downto 0 do
For i := 8*maxRounds-1 downto 0 do
dummy(@Rule30_State[0]);
dummy(@Rule30_State[0]);
T1 := time;
T1 := time;
Line 444: Line 443:
// Takte pro Durchlauf
// Takte pro Durchlauf
writeln('cycles per call : ',((T1-t0)*86400*CpuF)/(maxRounds):0:2);
writeln('cycles per call : ',((T1-t0)*86400*CpuF)/(maxRounds):0:2);
Out_Rule30_State;
Ausgabe;
T0 := time;
T0 := time;
For i := maxRounds-1 downto 0 do
For i := maxRounds-1 downto 0 do
Begin
Next_State_Rule_30(@Rule30_State[0]);
b := 0;
For j := 7 downto 0 do
Begin
b := (b+b) OR (Rule30_State[0] AND 1);
Next_State_Rule_30(@Rule30_State[0]);
end;
end;
T1 := time;
T1 := time;
Out_Rule30_State;
Ausgabe;
writeln(maxRounds,' calls take ',FormatDateTime('HH:NN:SS.zzz',T1-T0));
writeln(maxRounds,' calls take ',FormatDateTime('HH:NN:SS.zzz',T1-T0));
writeln('cycles per call : ',((T1-t0)*86400*CpuF)/maxRounds:0:2);
writeln('cycles per Byte : ',((T1-t0)*86400*CpuF)/maxRounds:0:2);
writeln;
writeln;
end;
end;
Line 479: Line 485:
Task;
Task;
readln;
readln;
end.
end.</lang>
</lang>
{{out}}
{{out}}
<pre>
<pre>Speedtest for statesize of 64 bits
Speedtest for statesize of 64 bits
Dummy calls 00:00:00.140
Dummy calls 00:00:00.031
cycles per call : 5.18
cycles per call : 57.35
0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 1_00000001D_00000000
0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 0_00000000 1_00000001D_00000000
206_11001110 118_01110110 103_01100111 126_01111110 188_10111100 192_11000000 103_01100111 206_11001110D_11001110
247_11110111 53_00110101 233_11101001 101_01100101 155_10011011 150_10010110 206_11001110 177_10110001D_11110111
100000000 calls take 00:00:00.445
2000000 calls take 00:00:00.069
cycles per call : 16.46
cycles per Byte : 127.65


The task
The task