Skip to content

Commit 1179f3e

Browse files
authored
Merge pull request #4 from 314eter/improved-mergesort
Improved mergesort solution
2 parents 864daa4 + 1e9d580 commit 1179f3e

1 file changed

Lines changed: 39 additions & 66 deletions

File tree

solutions/mergesort_par.ml

Lines changed: 39 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,78 +3,51 @@ module T = Domainslib.Task
33
let num_domains = try int_of_string @@ Sys.argv.(1) with _ -> 1
44
let n = try int_of_string @@ Sys.argv.(2) with _ -> 1024
55

6-
let min = 128
7-
let pool = T.setup_pool ~num_additional_domains:(num_domains - 1) ()
6+
let bubble_sort_threshold = 32
87

98
let _ = Random.init 42
109
let a = Array.init n (fun _ -> Random.int n)
11-
let b = Array.make n 0
1210

13-
type array_slice = {arr: int array; index: int; length: int}
14-
15-
let sort a =
16-
for i = a.index to a.index + a.length - 2 do
17-
for j = i + 1 to a.index + a.length - 1 do
18-
if a.arr.(j) < a.arr.(i) then
19-
let t = a.arr.(i) in
20-
a.arr.(i) <- a.arr.(j);
21-
a.arr.(j) <- t
11+
let bubble_sort (a : int array) start limit =
12+
for i = start to limit - 2 do
13+
for j = i + 1 to limit - 1 do
14+
if a.(j) < a.(i) then
15+
let t = a.(i) in
16+
a.(i) <- a.(j);
17+
a.(j) <- t;
2218
done
2319
done
2420

25-
let merge a b res =
26-
let rec loop ai bi ri =
27-
match a.index + a.length - ai, b.index + b.length - bi with
28-
| n, 0 -> Array.blit a.arr ai res.arr ri n
29-
| 0, n -> Array.blit b.arr bi res.arr ri n
30-
| _, _ ->
31-
if a.arr.(ai) < b.arr.(bi) then begin
32-
res.arr.(ri) <- a.arr.(ai);
33-
loop (ai+1) bi (ri+1)
34-
end else begin
35-
res.arr.(ri) <- b.arr.(bi);
36-
loop ai (bi+1) (ri+1)
37-
end
38-
in
39-
loop a.index b.index res.index
40-
41-
let rec merge_sort a b l =
42-
if a.length <= min then begin
43-
sort a;
44-
a
45-
end else
46-
let a1= {a with index = a.index; length = a.length / 2} in
47-
let b1 = {b with index = b.index; length = b.length / 2} in
48-
let r1 = T.async pool (fun _ -> merge_sort a1 b1 (2*l+1)) in
49-
50-
let a2 = {a with index = a.index + a.length / 2;
51-
length = a.length - a.length / 2} in
52-
let b2 = {b with index = b.index + b.length / 2;
53-
length = b.length - b.length / 2} in
54-
let r2 = T.async pool (fun _ -> merge_sort a2 b2 (2*l+2)) in
55-
56-
let (r1, r2) = (T.await pool r1, T.await pool r2) in
57-
58-
if r1.arr != r2.arr then begin
59-
if r2.arr == a.arr then begin
60-
merge r1 r2 a;
61-
a
62-
end else begin
63-
merge r1 r2 b;
64-
b
65-
end
66-
end else if r1.arr == a.arr then begin
67-
merge r1 r2 b;
68-
b
21+
let merge (src : int array) dst start split limit =
22+
let rec loop dst_pos i j =
23+
if i = split then
24+
Array.blit src j dst dst_pos (limit - j)
25+
else if j = limit then
26+
Array.blit src i dst dst_pos (split - i)
27+
else if src.(i) <= src.(j) then begin
28+
dst.(dst_pos) <- src.(i);
29+
loop (dst_pos + 1) (i + 1) j;
6930
end else begin
70-
merge r1 r2 a;
71-
a
72-
end
73-
74-
let _ =
75-
let aslice = {arr = a; index = 0; length = n}in
76-
let bslice = {arr = b; index = 0; length = n} in
77-
78-
let _r = T.run pool (fun _ -> merge_sort aslice bslice 0) in
79-
(* Array.iter (fun i -> print_endline (string_of_int i)) _r.arr; *)
31+
dst.(dst_pos) <- src.(j);
32+
loop (dst_pos + 1) i (j + 1);
33+
end in
34+
loop start start split
35+
36+
let rec merge_sort pool move a b start limit =
37+
if move || limit - start > bubble_sort_threshold then
38+
let split = (start + limit) / 2 in
39+
let r1 = T.async pool (fun () -> merge_sort pool (not move) a b start split) in
40+
let r2 = T.async pool (fun () -> merge_sort pool (not move) a b split limit) in
41+
T.await pool r1;
42+
T.await pool r2;
43+
if move then merge a b start split limit else merge b a start split limit
44+
else bubble_sort a start limit
45+
46+
let sort pool a =
47+
let b = Array.copy a in
48+
T.run pool (fun () -> merge_sort pool false a b 0 (Array.length a))
49+
50+
let () =
51+
let pool = T.setup_pool ~num_additional_domains:(num_domains - 1) () in
52+
sort pool a;
8053
T.teardown_pool pool

0 commit comments

Comments
 (0)