Skip to content

Instantly share code, notes, and snippets.

@rbehrends
Last active August 29, 2015 14:00
Show Gist options
  • Save rbehrends/cf84a2cd8b407f4fc612 to your computer and use it in GitHub Desktop.
Save rbehrends/cf84a2cd8b407f4fc612 to your computer and use it in GitHub Desktop.
import mersenne, times, locks
const
N = 8
M = 8
iters = 1000
numThreads = 8
type
SVec = array[0..N+M-1, int]
FVec = array[0..N-1, int]
ComputeThread = TThread[int]
var
rngSeed = int(epochTime()*1000)
totalLeadingZeros: array[0..M-1, int]
lock: TLock
proc initVecRand(v: var FVec, rng: var TMersenneTwister) =
var rnd = rng.getNum()
var bitAcc = 0
for i in 0 .. <len(v):
let m = rnd and 3
rnd = rnd shr 2
v[i] = if m <= 2: m-1 else: 0
bitAcc = bitAcc or v[i]
if bitAcc == 0:
initVecRand(v, rng)
proc convolve(s: SVec, f: FVec, offset: int): int =
for i in 0 .. <len(f):
result += s[i+offset]*f[i]
proc advance(v: var SVec) =
for i in 0 .. <len(v):
if v[i] == -1:
v[i] = 1
return
v[i] = -1
proc mainThread(id: int) {.thread.} =
const numS = 1 shl (N+M-1)
var
s: SVec
f: FVec
leadingZeros: array[0..M-1, int]
rngState = newMersenneTwister(rngSeed + id)
for k in 0 .. <len(s):
s[k] = -1
for i in 1..numS:
for j in countUp(1, iters, numThreads):
initVecRand(f, rngState)
if convolve(s, f, 0) == 0:
leadingZeros[0] += 1
for k in 1 .. <M:
if convolve(s, f, k) == 0:
leadingZeros[k] += 1
else:
break
s.advance
acquire(lock)
for i in 0 .. <M:
totalLeadingZeros[i] += leadingZeros[i]
release(lock)
proc main =
var threads: array[1..numThreads, ComputeThread]
initLock(lock)
for i in 1..numThreads:
createThread(threads[i], mainThread, i)
for i in 1..numThreads:
joinThread(threads[i])
echo(@totalLeadingZeros)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment