Just trying to learn Nim by going through the problems on "Rosetta Code". I 
wrote a Nim version for the "100 Prisonsers" problem - 
[http://rosettacode.org/wiki/100_prisoners#Nim](http://rosettacode.org/wiki/100_prisoners#Nim)
 \- and wanted to speed up things by going multi-core. Unfortunately the 
multi-core version is slower than the single-core one and I don't have a clue 
why.
    
    
    import random, sequtils, strutils, threadpool, cpuinfo
    
    type
      Sample = tuple
        succ: int
        fail: int
    
    const
      numPrisoners = 100
      numDrawsEachPrisoner = numPrisoners div 2
      numDrawings = 1_000_000 div 1
    
    proc `$`(s: Sample): string =
      "Succs: $#\tFails: $#\tTotal: $#\tSuccess Rate: $#%." % [$s.succ, 
$s.fail, $(s.succ + s.fail), $(s.succ.float / numDrawings.float * 100.0)]
    
    proc prisonersWillBeReleasedSmart(): bool =
      result = true
      var drawers = toSeq(0..<numPrisoners)
      drawers.shuffle
      for prisoner in 0..<numPrisoners:
        var drawer = prisoner
        block inner:
          for _ in 0..<numDrawsEachPrisoner:
            if drawers[drawer] == prisoner: break inner
            drawer = drawers[drawer]
          return false
    
    proc prisonersWillBeReleasedRandom(): bool =
      result = true
      var drawers = toSeq(0..<numPrisoners)
      drawers.shuffle
      for prisoner in 0..<numPrisoners:
        var selectDrawer = toSeq(0..<numPrisoners)
        selectDrawer.shuffle
        block inner:
          for i in 0..<numDrawsEachPrisoner:
            if drawers[selectDrawer[i]] == prisoner: break inner
          return false
    
    proc bulkDrawings(n: int, prisonersWillBeReleased: proc(): bool): Sample =
      for _ in 1..n:
        if prisonersWillBeReleased():
          result = (result.succ + 1, result.fail)
        else:
          result = (result.succ, result.fail + 1)
    
    proc massDrawings(prisonersWillBeReleased: proc(): bool): Sample =
      var succFails = newSeqOfCap[FlowVar[Sample]](countProcessors())
      for _ in 1..countProcessors():
        succFails.add(spawn bulkDrawings(numDrawings div countProcessors(), 
prisonersWillBeReleased))
      for resp in succFails:
        let response = ^resp
        result = (result.succ + response.succ, result.fail + response.fail)
    
    randomize()
    echo $massDrawings(prisonersWillBeReleasedSmart)
    echo $massDrawings(prisonersWillBeReleasedRandom)
    
    
    Run

Reply via email to