It's all rather funny.

First of all, if you're insisting on using `std/threadpool` and it so happens 
that you use `--gc:orc` (or, like me, have it set in your config asthea 
default) you get `SIGSEGV: Illegal storage access. (Attempt to read from 
nil?)`. Arc is of course much **much** slower than refc due to this reckless 
seq galore.

Also, it's rather hard for a beginner to deduce from the threadpool docs the 
correct way to use it ("cast?", "so, should I `while` until I get -1 or no?").

Finally, I had to use `std/monotimes`, as `cpuTime` measurements for this code 
outputs are completely off, which is probably expected, but not stressed enough 
in the docs.
    
    
    # nim c --threads:on -d:release --gc:arc stt.nim && time ./stt
    import std/[threadpool, times, strutils, strformat, monotimes]
    
    proc splitToTerms(n:int, k:int): seq[seq[int]] =
      let kk = if k == 0: n else: k
      if n != 0:
        result = newSeq[seq[int]]()
        if n <= kk:
          result.add(@[n])
        for i in 1 .. min(n, kk):
          for l in splitToTerms(n-1, i):
            result.add(l&(@[i]))
    
    proc threaded(n:int): seq[int] =
      var futures = newSeq[FlowVarBase](n)
      let startTime = cpuTime()
      let startMT = getMonoTime()
      
      for i in 1..n: # indexing to keep ordering
        futures[i-1] = spawn splitToTerms(n,i)
      result = newSeq[int](n)
      for _ in 1..n:
        let futIdx = futures.blockUntilAny()
        if futIdx != -1:
          let r = ^cast[FlowVar[seq[seq[int]]]](futures[futIdx])
          let dur = (getMonoTime() - startMT).inMilliseconds()
          echo &"res#{futIdx+1} len={r.len} in {dur} ms"
          result[futIdx] = r.len()
        else:
          break
    
    const N=10
    echo threaded(N)
    
    
    Run

Reply via email to