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; |
||
⚫ | |||
//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 |
||
⚫ | |||
{$IFDEF FPC} |
{$IFDEF FPC} |
||
{$Mode Delphi} |
{$Mode Delphi} |
||
Line 324: | Line 324: | ||
SysUtils; |
SysUtils; |
||
const |
const |
||
maxRounds = |
maxRounds = 2*1000*1000; |
||
rounds = 10; |
rounds = 10; |
||
Line 330: | Line 330: | ||
const |
const |
||
RULE30_BITSIZE = |
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 |
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 // |
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 // 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 |
|||
⚫ | |||
b := 0; |
|||
For j := 7 downto 0 do |
|||
Begin |
|||
b := (b+b) OR (Rule30_State[0] AND 1); |
|||
⚫ | |||
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 |
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> |
|||
Speedtest for statesize of 64 bits |
|||
Dummy calls 00:00:00. |
Dummy calls 00:00:00.031 |
||
cycles per call : |
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 |
|||
2000000 calls take 00:00:00.069 |
|||
cycles per |
cycles per Byte : 127.65 |
||
The task |
The task |