Skip to content

Instantly share code, notes, and snippets.

@sanette
Last active January 18, 2023 16:04
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 sanette/b27e21ef9252b3862ca62d2c30b62027 to your computer and use it in GitHub Desktop.
Save sanette/b27e21ef9252b3862ca62d2c30b62027 to your computer and use it in GitHub Desktop.
(** Here is a very simple OCaml implementation of the computation of the dot
product of two large arrays of floats, using the new [Domain]
module. This requires ocaml >= 5.0.0
Here is how to compile to byte-code:
ocamlfind ocamlc -package unix -linkpkg -o dot dot.ml
Here is how to compile to native code:
ocamlfind ocamlopt -package unix -linkpkg -o dot dot.ml
Here are the results (of executing [./dot]) on my laptop:
Bytecode result:
Sequential execution: 0.350471ms
Parallel execution on 2 domains: 0.186699ms
Nativecode result:
Sequential execution: 0.016154ms
Parallel execution on 2 domains: 0.009750ms
*)
let num_domains = 2
(** Sequential implementation of the dot product of the sub-arrays of
[a] and [b] of length [l] starting at index [i]. *)
let dot_seq a b i l =
let x = ref 0. in
for j = i to i+l-1 do
x := !x +. a.(j) *. b.(j)
done;
!x
(** Dot product of [a] and [b]. Parallel implementation, which simply
splits the array into [num_domains] subarrays, each of which is
computed sequentially by [dot_seq], and finally combines the
results to sum them. *)
let dot a b =
let n = Array.length a in
assert (n = Array.length b);
let l = n / num_domains in
let rec loop i d spawns =
if d = 0 then spawns
else let l = if d = 1 then n - i else l in
loop (i+l) (d-1)
((Domain.spawn (fun () -> dot_seq a b i l)) :: spawns) in
loop 0 num_domains []
|> List.map Domain.join
|> List.fold_left ( +. ) 0.
(* Tests *)
let n = 10_000_001
let a = Array.init n float
let b = Array.make n 0.5
let x = float (n*(n-1))/. 4.
let t = Unix.gettimeofday () in
assert (dot_seq a b 0 n = x);
Printf.printf "Sequential execution: %fms\n"
(Unix.gettimeofday () -. t);;
let t = Unix.gettimeofday () in
assert (dot a b = x);
Printf.printf "Parallel execution on %i domains: %fms\n"
num_domains (Unix.gettimeofday () -. t);;
(* end of file *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment