Last active
January 18, 2023 16:04
-
-
Save sanette/b27e21ef9252b3862ca62d2c30b62027 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(** 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