From 2f0cf1970ebf306a3a836bf292f4bebdacdb70ad Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 30 May 2023 23:52:09 -0400 Subject: [PATCH] require ocaml >= 4.05; use mdx for the readme --- .github/workflows/main.yml | 2 +- README.md | 67 ++++++++++++++++++++++++++++++++++++++ dune | 2 +- dune-project | 2 +- moonpool.opam | 2 +- 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 README.md diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b2fab248..0ea1bb31 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest #- windows-latest ocaml-compiler: - - '4.03.x' + - '4.05.x' - '4.14.x' - '5.0.x' diff --git a/README.md b/README.md new file mode 100644 index 00000000..b38a67bd --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# Moonpool + +A pool within a bigger pool (ie the ocean). Here, we're talking about +pools of [Thread.t] which live within a fixed pool of [Domain.t]. + +## Usage + +The user can create several thread pools. These pools use regular posix threads, +but the threads are spread across multiple domains (on OCaml 5), which enables +parallelism. + +```ocaml +# #require "moonpool";; +# let pool = Moonpool.Pool.create ~min:4 ();; +val pool : Moonpool.Pool.t = + +# let rec fib x = + if x <= 1 then 1 else fib (x-1) + fib (x-2);; +val fib : int -> int = + +# List.init 10 fib;; +- : int list = [1; 1; 2; 3; 5; 8; 13; 21; 34; 55] + +# let fibs = Array.init 30 (fun n -> Moonpool.Fut.spawn ~on:pool (fun () -> fib n));; +val fibs : int Moonpool.Fut.t array = + [|; ; ; ; ; ; ; ; + ; ; ; ; ; ; ; ; + ; ; ; ; ; ; ; ; + ; ; ; ; ; |] + +# Moonpool.Fut.join_array fibs |> Moonpool.Fut.wait_block;; +- : int array Moonpool.or_error = +Ok + [|1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89; 144; 233; 377; 610; 987; 1597; 2584; + 4181; 6765; 10946; 17711; 28657; 46368; 75025; 121393; 196418; 317811; + 514229; 832040|] +``` + +## OCaml versions + +This works for OCaml >= 4.05. +- On OCaml 4.xx, there are no domains, so this is just a library for regular thread pools + with not actual parallelism (except for threads that call C code that releases the runtime lock, that is). +- on OCaml 5.xx, there is a fixed pool of domains (using the recommended domain count). + These domains do not do much by themselves, but we schedule new threads on them, and group + threads from each domain into pools. + Each domain might thus have multiple threads that belong to distinct pools (and several threads from + the same pool, too — this is useful for threads blocking on IO). + + A useful analogy is that each domain is a bit like a CPU core, and `Thread.t` is a logical thread running on a core. + Multiple threads have to share a single core and do not run in parallel on it[^1]. + We can therefore build pools that spread their worker threads on multiple cores to enable parallelism within each pool. + +TODO: actually use https://github.com/haesbaert/ocaml-processor to pin domains to cores, +possibly optionally using `select` in dune. + +## License + +MIT license. + +## Install + +```sh, skip +$ opam install moonpool +``` + +[^1]: let's not talk about hyperthreading. diff --git a/dune b/dune index 4227a1ef..aa3b8797 100644 --- a/dune +++ b/dune @@ -1,5 +1,5 @@ (env - (_ (flags :standard -strict-sequence -warn-error -a+8 -w +a-40-70))) + (_ (flags :standard -strict-sequence -warn-error -a+8 -w +a-4-40-70))) (mdx) diff --git a/dune-project b/dune-project index c8cf0cd4..1d7a24f2 100644 --- a/dune-project +++ b/dune-project @@ -21,7 +21,7 @@ (name moonpool) (synopsis "Pools of threads supported by a pool of domains") (depends - ocaml + (ocaml (>= 4.05)) dune (mdx (and diff --git a/moonpool.opam b/moonpool.opam index 64dc845e..a19a8a27 100644 --- a/moonpool.opam +++ b/moonpool.opam @@ -8,7 +8,7 @@ tags: ["thread" "pool" "domain"] homepage: "https://github.com/c-cube/moonpool" bug-reports: "https://github.com/c-cube/moonpool/issues" depends: [ - "ocaml" + "ocaml" {>= "4.05"} "dune" {>= "3.0"} "mdx" {>= "1.9.0" & with-test} "odoc" {with-doc}