Last active
August 3, 2021 21:15
-
-
Save aike/d0d0a5a12c265c5e1fbd07d793919185 to your computer and use it in GitHub Desktop.
KSP random function benchmark / 10000 loop result: random() 827microsec, LCG 857microsec, MT 11498microsec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{========================================== | |
random function benchmark | |
==========================================} | |
on init | |
set_ui_height_px(120) | |
make_perfview | |
set_script_title("random function benchmark") | |
declare ui_label $label1(1, 1) | |
declare ui_label $label2(1, 1) | |
declare ui_label $label3(1, 1) | |
move_control($label1, 1, 2) | |
move_control($label2, 1, 3) | |
move_control($label3, 1, 4) | |
set_text($label1, "random") | |
set_text($label2, "MT") | |
set_text($label3, "LCG") | |
declare ui_label $result1(1, 1) | |
declare ui_label $result2(1, 1) | |
declare ui_label $result3(1, 1) | |
move_control($result1, 2, 2) | |
move_control($result2, 2, 3) | |
move_control($result3, 2, 4) | |
set_text($result1, "") | |
set_text($result2, "") | |
set_text($result3, "") | |
declare $n | |
declare $r | |
declare const $loop := 10000 | |
{========================================== | |
Linear Congruential Generator | |
==========================================} | |
{ LCG access variables } | |
declare $lcg_seed | |
$lcg_seed := 0 | |
declare $lcg_rand | |
declare $lcg_next | |
{========================================== | |
Mersenne Twister (MT19937) | |
==========================================} | |
{ MT access variables } | |
declare $mt_seed | |
$mt_seed := 0 | |
declare $mt_rand | |
{ MT xor helper variables } | |
declare $mt_xor_arg1 | |
declare $mt_xor_arg2 | |
declare $mt_xor_tmp_or | |
declare $mt_xor_tmp_nand | |
declare $mt_xor_result | |
{ MT Period parameters } | |
declare const $mt_N := 624 | |
declare const $mt_M := 397 | |
declare const $mt_MATRIX_A := 09908b0dfh | |
declare const $mt_UPPER_MASK := 080000000h | |
declare const $mt_LOWER_MASK := 07fffffffh | |
declare %mt_x[$mt_N] | |
declare $mt_i | |
declare $mt_y | |
declare $mt_z | |
{ MT initialize array with $mt_seed } | |
%mt_x[0] := $mt_seed .and. 0ffffffffh | |
$mt_i := 1 | |
while ($mt_i < $mt_N) | |
$mt_xor_arg1 := %mt_x[$mt_i - 1] | |
$mt_xor_arg2 := sh_right(%mt_x[$mt_i - 1] .and. $mt_LOWER_MASK, 30) | |
if (%mt_x[$mt_i - 1] < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2 | |
end if | |
$mt_xor_tmp_or := $mt_xor_arg1 .or. $mt_xor_arg2 | |
$mt_xor_tmp_nand := .not. ($mt_xor_arg1 .and. $mt_xor_arg2) | |
$mt_xor_result := $mt_xor_tmp_or .and. $mt_xor_tmp_nand | |
%mt_x[$mt_i] := (1812433253 * $mt_xor_result) + $mt_i | |
%mt_x[$mt_i] := %mt_x[$mt_i] .and. 0ffffffffh | |
inc($mt_i) | |
end while | |
$mt_i := 0 | |
message("") | |
end on | |
{ MT helper function calculate $mt_xor_arg1 XOR $mt_xor_arg2 } | |
function mt_xor | |
$mt_xor_tmp_or := $mt_xor_arg1 .or. $mt_xor_arg2 | |
$mt_xor_tmp_nand := .not. ($mt_xor_arg1 .and. $mt_xor_arg2) | |
$mt_xor_result := $mt_xor_tmp_or .and. $mt_xor_tmp_nand | |
end function | |
{ MT initialize array with $mt_seed } | |
function mt_init | |
%mt_x[0] := $mt_seed .and. 0ffffffffh | |
$mt_i := 1 | |
while ($mt_i < $mt_N) | |
$mt_xor_arg1 := %mt_x[$mt_i - 1] | |
$mt_xor_arg2 := sh_right(%mt_x[$mt_i - 1] .and. $mt_LOWER_MASK, 30) | |
if (%mt_x[$mt_i - 1] < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2 | |
end if | |
call mt_xor | |
%mt_x[$mt_i] := (1812433253 * $mt_xor_result) + $mt_i | |
%mt_x[$mt_i] := %mt_x[$mt_i] .and. 0ffffffffh | |
inc($mt_i) | |
end while | |
$mt_i := 0 | |
end function | |
{ MT generates a random number } | |
function mt_genrand | |
$mt_z := %mt_x[$mt_i] .and. $mt_UPPER_MASK | |
$mt_z := $mt_z .or. (%mt_x[($mt_i + 1) mod $mt_N] .and. $mt_LOWER_MASK) | |
$mt_xor_arg1 := %mt_x[($mt_i + $mt_M) mod $mt_N] | |
$mt_xor_arg2 := sh_right($mt_z .and. $mt_LOWER_MASK, 1) | |
if ($mt_z < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 040000000h | |
end if | |
call mt_xor | |
$mt_xor_arg1 := $mt_xor_result | |
if (($mt_z .and. 1) = 0) | |
$mt_xor_arg2 := 0 | |
else | |
$mt_xor_arg2 := $mt_MATRIX_A | |
end if | |
call mt_xor | |
%mt_x[$mt_i] := $mt_xor_result | |
$mt_y := %mt_x[$mt_i] | |
{ Tempering } | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_right($mt_y .and. $mt_LOWER_MASK, 11) | |
if ($mt_y < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 100000h | |
end if | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_left($mt_y, 7) .and. 09d2c5680h | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_left($mt_y, 15) .and. 0efc60000h | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_right($mt_y .and. $mt_LOWER_MASK, 18) | |
if ($mt_y < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2000h | |
end if | |
call mt_xor | |
$mt_y := $mt_xor_result | |
{ get 31bit unsigned int } | |
$mt_rand := sh_right($mt_y .and. $mt_LOWER_MASK, 1) | |
if ($mt_y < 0) | |
$mt_rand := $mt_rand .or. 040000000h | |
end if | |
$mt_i := ($mt_i + 1) mod $mt_n | |
end function | |
{ LCG initialize array with $mt_seed } | |
function lcg_init | |
$lcg_next := $lcg_seed | |
end function | |
{ LCG generates a random number } | |
function lcg_genrand | |
$lcg_next := $lcg_next * 1103515245 + 12345 | |
$lcg_rand := sh_right($lcg_next .and. 07fffffffh, 16) | |
end function | |
on note | |
reset_ksp_timer | |
$n := 0 | |
while($n < $loop) | |
$r := random(0, 7fffh) | |
inc($n) | |
end while | |
set_text($result1, $KSP_TIMER & " microsec") | |
reset_ksp_timer | |
$n := 0 | |
while($n < $loop) | |
call mt_genrand | |
$r := $mt_rand | |
inc($n) | |
end while | |
set_text($result2, $KSP_TIMER & " microsec") | |
reset_ksp_timer | |
$n := 0 | |
while($n < $loop) | |
call lcg_genrand | |
$r := $lcg_rand | |
inc($n) | |
end while | |
set_text($result3, $KSP_TIMER & " microsec") | |
end on |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment