Skip to content

Instantly share code, notes, and snippets.

@mratsim
Last active November 11, 2019 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mratsim/cb088bed2d69aa691c87360472e4bd7f to your computer and use it in GitHub Desktop.
Save mratsim/cb088bed2d69aa691c87360472e4bd7f to your computer and use it in GitHub Desktop.
Some design questions on Threading API
  • Atomic Rc vs Rc taxes for single-threaded module compile with threads:on

  • API to allow to switch runtimes:

    • Simple threadpool, custom one
    • Throughput optimized (work-stealing)
    • Latency-optimized (Earliest Deadline First schedulers / priority queues)
    • Plug in Cuda/OpenCL async (Streams and Command Queue) or external system like MPI, (Hadoop/Kafka?) etc
  • 2 spawns

    • spawn that access a global default threadpool for Nim programs composability
    • spawn that takes a threadpool as first argument
  • await (or fetch or sync) is better than ^

  • If we use "sync" we would have the following consistency

    var globalBarrier: PthreadBarrier
    
    proc sync() =
      # Blocking until all threads went through this glocal barrier
      globalBarrier.wait()
    
    proc sync[T](fv: Flowvar[T]): T =
      # Blocking until future is ready
      fv.get()
     
    proc sync(barrier: PthreadBarrier) =
      # Blocking until all threads went through this local barrier
      barrier.wait()
      
    # The "local" barrier would be use like so
    proc sumThenDo(x: ptr UncheckedArray[int], len: int, sum: var int, callBack: proc(x: ptr int): int): int =
      var localSum {.threadvar.}: int
      # Even though it only exists in the proc, it needs the global tag for visibility across threads
      var scopedBarrier {.global.}: PthreadBarrier 
      parallelRegion:
        parfor i in 0 ..< len:
          localsum += x[i]
        discard sum.fetchAdd(localSum, moRelease)
        sync(scopedBarrier)
        let c = spawn callBack(sum)
        discard result.fetchAdd(sync(c), moRelease)
  • Typesafe tags:

    • T.supportsCopyMem for deep copyable types: can we have a Concept or Trait for that? (equivalent to Rust "Send")
    • "Sync" / "Shareable" for types which can be shared by pointers (but may or may not be copyable because it also holds a resource) Concept or Trait for that?

"exportc" names to be usable in JIT or from C:

import mythreadpools

type Foo{.exportc.} = object
  a: int32
  b: int32

proc spawnMyProcessingRoutine(foo: ptr UncheckedArray[Foo], arg1, arg2: Foo) {.exportC.} =
  # wrapping the spawn macro/template/proc of any multithreading runtime
  # for C/JIT comsumption is actually easy
  spawn myProcessingProc(foo, arg1, arg2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment