Nim Concurrency and Parallelism

Introduction

Nim supports both threads and async/await for concurrency. New libraries are also expanding the choices developers have for concurrency and parallelism.

Parallel and Spawn

According to the Nim v1.2 manual, the new preferred way to achieve parallelism in Nim is to use parallel and/or spawn, found in the threadpool module. Spawn passes a specified task (a procedure) to the threadpool. Parallel creates a section to execute a block in parallel.

Links:

Nim in Action

Notable chapters:

  • Chapter 3: has a chat application that uses async.
  • Chapter 6: concurreny and parallelism (threads).

Example code: https://github.com/dom96/nim-in-action-code

Threads

In Nim threads are used as in most languages. The typical approach is that you create a number of threads using createThread() and wait for all of them to finish using joinThreads().

Threads are useful for when you can easily divide work up across a known number. However, knowing the number of threads to use can be difficult. The number of cores in the system can be used as an indicator, but the assumption is that these cores are free for your program to use.

Using threads can be difficult if memory is shared between threads, and that memory is modified by multiple threads. This can introduce bugs that are difficult to detect and fix. You can use locks to handle this. A lock is often called a mutex is other languages.

Links:

Async/await

Async/await is useful for when you want the main thread to keep running, but start work asynchronously, and later wait for the result. This pattern is especially useful in networking and database calls, where you are typically waiting for IO, but your program can keep working while waiting for the result of the IO.

Links:

Weave

Weave is a multi-threading runtime: https://github.com/mratsim/weave.

Features:

  • Message-passing based.
  • Scalable to available cores.
  • Fast and low-overhead.
  • Based on futures similar to async/await for concurrency.

Note the current limitations: “Weave has not been tested with GC-ed types. Pass a pointer around or use Nim channels which are GC-aware. If it works, a heads-up would be valuable. This might improve with Nim ARC/new runtime.”

Actor Model

Nim doesn’t have an actors framework/library that is maintained at present.

Parallelism in the Database

Most databases allow for parallelism, especially when working with set operators like UNION or when querying partitions. Details of database parallelism are out of scope for this article, but worth keeping in mind when performance tuning a system that uses a database.