@@ -3,78 +3,51 @@ module T = Domainslib.Task
33let num_domains = try int_of_string @@ Sys. argv.(1 ) with _ -> 1
44let 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
98let _ = Random. init 42
109let 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