Skip to content

Commit a786746

Browse files
committed
MersenneTwister: more efficient Float64 scalar generation with caching
Like for integers, a cache of size 8016 bytes seems to be optimal.
1 parent fdd926e commit a786746

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

base/random/RNGs.jl

+5-3
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ srand(rng::RandomDevice) = rng
6060

6161
## MersenneTwister
6262

63-
const MT_CACHE_F = dsfmt_get_min_array_size()
64-
const MT_CACHE_I = 501 << 4
63+
const MT_CACHE_F = 501 << 1 # number of Float64 in the cache
64+
const MT_CACHE_I = 501 << 4 # number of bytes in the UInt128 cache
65+
66+
@assert dsfmt_get_min_array_size() <= MT_CACHE_F
6567

6668
mutable struct MersenneTwister <: AbstractRNG
6769
seed::Vector{UInt32}
@@ -72,7 +74,7 @@ mutable struct MersenneTwister <: AbstractRNG
7274
idxI::Int
7375

7476
function MersenneTwister(seed, state, vals, ints, idxF, idxI)
75-
length(vals) == MT_CACHE_F && 0 <= idxF <= MT_CACHE_F ||
77+
length(vals) >= MT_CACHE_F && 0 <= idxF <= length(vals) ||
7678
throw(DomainError((length(vals), idxF),
7779
"`length(vals)` and `idxF` must be consistent with $MT_CACHE_F"))
7880
length(ints) == MT_CACHE_I >> 4 && 0 <= idxI <= MT_CACHE_I ||

test/random.jl

+7-7
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let A = zeros(2, 2)
3838
end
3939
let A = zeros(2, 2)
4040
@test_throws ArgumentError rand!(MersenneTwister(0), A, 5)
41-
@test rand(MersenneTwister(0), Int64, 1) == [5986602421100169002]
41+
@test rand(MersenneTwister(0), Int64, 1) == [2118291759721269919]
4242
end
4343
let A = zeros(Int64, 2, 2)
4444
rand!(MersenneTwister(0), A)
@@ -278,10 +278,10 @@ let mt = MersenneTwister(0)
278278
B = Vector{T}(uninitialized, 31)
279279
rand!(mt, A)
280280
rand!(mt, B)
281-
@test A[end] == Any[21, 0x4e, -3158, 0x0ded, 2132370312, 0x5e76d222, 1701112237820550475, 0xde7c8e58fb113739,
282-
-17260403799139981754163727590537874047, Float16(0.90234), 0.0909704f0][i]
283-
@test B[end] == Any[94, 0xb8, 3111, 0xefa4, 411531475, 0xd8089c1d, -7344871485543005232, 0xedb4b5c61c037a43,
284-
-118178167582054157562031602894265066400, Float16(0.91211), 0.2516626f0][i]
281+
@test A[end] == Any[21, 0x4e, -3158, 0x0ded, 2132370312, 0x5e76d222, 1701112237820550475, 0x552ac662d46426bf,
282+
-48946429529471164341432530784191877404, Float16(0.99805), 0.845204f0][i]
283+
@test B[end] == Any[94, 0x14, 22684, 0x0278, -862240437, 0xc425026c, -7329373301769527751, 0x8a40806d8107ce23,
284+
37650272825719887492093881479739648820, Float16(0.14648), 0.5025569f0][i]
285285
end
286286

287287
srand(mt, 0)
@@ -290,7 +290,7 @@ let mt = MersenneTwister(0)
290290
@test rand!(mt, AF64)[end] == 0.6492481059865669
291291
resize!(AF64, 2*length(mt.vals))
292292
@test invoke(rand!, Tuple{MersenneTwister,AbstractArray{Float64},Base.Random.SamplerTrivial{Base.Random.CloseOpen_64}},
293-
mt, AF64, Base.Random.SamplerTrivial(Base.Random.CloseOpen()))[end] == 0.432757268470779
293+
mt, AF64, Base.Random.SamplerTrivial(Base.Random.CloseOpen()))[end] == 0.1142787906708973
294294
end
295295

296296
# Issue #9037
@@ -313,7 +313,7 @@ let mt = MersenneTwister(0)
313313
srand(mt, 0)
314314
rand(mt) # this is to fill mt.vals, cf. #9040
315315
rand!(mt, A) # must not segfault even if Int(pointer(A)) % 16 != 0
316-
@test A[end-4:end] == [0.49508297796349776,0.3408340446375888,0.3211229457075784,0.9103565379264364,0.16456579813368521]
316+
@test A[end-4:end] == [0.3371041633752143, 0.41147647589610803, 0.6063082992397912, 0.9103565379264364, 0.16456579813368521]
317317
end
318318
end
319319

0 commit comments

Comments
 (0)