ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/BoxedLongSort.java
Revision: 1.6
Committed: Mon Oct 10 16:59:04 2011 UTC (12 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.5: +2 -2 lines
Log Message:
whitespace

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import java.util.concurrent.*;
8 import java.util.*;
9
10 class BoxedLongSort {
11 static final long NPS = (1000L * 1000 * 1000);
12
13 static int THRESHOLD;
14 static final boolean warmup = true;
15
16 public static void main(String[] args) throws Exception {
17 int procs = 0;
18 int n = 1 << 22;
19 int reps = 20;
20 int sreps = 2;
21 try {
22 if (args.length > 0)
23 procs = Integer.parseInt(args[0]);
24 if (args.length > 1)
25 n = Integer.parseInt(args[1]);
26 if (args.length > 2)
27 reps = Integer.parseInt(args[1]);
28 }
29 catch (Exception e) {
30 System.out.println("Usage: java BoxedLongSort threads n reps");
31 return;
32 }
33 ForkJoinPool pool = (procs == 0) ? new ForkJoinPool() :
34 new ForkJoinPool(procs);
35
36 Long[] a = new Long[n];
37 seqRandomFill(a, 0, n);
38
39 if (warmup) {
40 System.out.printf("Sorting %d longs, %d replications\n", n, 1);
41 Collections.shuffle(Arrays.asList(a));
42 long last = System.nanoTime();
43 java.util.Arrays.sort(a);
44 double elapsed = (double)(System.nanoTime() - last) / NPS;
45 System.out.printf("Arrays.sort time: %7.3f\n", elapsed);
46 checkSorted(a);
47 }
48
49 // for now hardwire 8 * #CPUs leaf tasks
50 THRESHOLD = 1 + ((n + 7) >>> 3) / pool.getParallelism();
51 // THRESHOLD = 1 + ((n + 15) >>> 4) / pool.getParallelism();
52 // THRESHOLD = 1 + ((n + 31) >>> 5) / pool.getParallelism();
53
54 System.out.printf("Sorting %d longs, %d replications\n", n, reps);
55 for (int i = 0; i < reps; ++i) {
56 Collections.shuffle(Arrays.asList(a));
57 // pool.invoke(new RandomFiller(a, 0, n));
58 long last = System.nanoTime();
59 pool.invoke(new Sorter(a, new Long[n], 0, n));
60 double elapsed = (double)(System.nanoTime() - last) / NPS;
61 System.out.printf("Parallel sort time: %7.3f\n", elapsed);
62 if (i == 0)
63 checkSorted(a);
64 }
65 System.out.println(pool);
66
67 System.out.printf("Sorting %d longs, %d replications\n", n, sreps);
68 for (int i = 0; i < sreps; ++i) {
69 Collections.shuffle(Arrays.asList(a));
70 // pool.invoke(new RandomFiller(a, 0, n));
71 long last = System.nanoTime();
72 java.util.Arrays.sort(a);
73 double elapsed = (double)(System.nanoTime() - last) / NPS;
74 System.out.printf("Arrays.sort time: %7.3f\n", elapsed);
75 if (i == 0)
76 checkSorted(a);
77 }
78 System.out.println(pool);
79 pool.shutdown();
80 }
81
82 static final class Sorter extends RecursiveAction {
83 final Long[] a;
84 final Long[] w;
85 final int origin;
86 final int n;
87 Sorter(Long[] a, Long[] w, int origin, int n) {
88 this.a = a; this.w = w; this.origin = origin; this.n = n;
89 }
90
91 public void compute() {
92 int l = origin;
93 if (n <= THRESHOLD)
94 Arrays.sort(a, l, l+n);
95 else { // divide in quarters to ensure sorted array in a not w
96 int h = n >>> 1;
97 int q = n >>> 2;
98 int u = h + q;
99 SubSorter rs = new SubSorter
100 (new Sorter(a, w, l+h, q),
101 new Sorter(a, w, l+u, n-u),
102 new Merger(a, w, l+h, q, l+u, n-u, l+h, null));
103 rs.fork();
104 Sorter rl = new Sorter(a, w, l+q, h-q);
105 rl.fork();
106 (new Sorter(a, w, l, q)).compute();
107 rl.join();
108 (new Merger(a, w, l, q, l+q, h-q, l, null)).compute();
109 rs.join();
110 new Merger(w, a, l, h, l+h, n-h, l, null).compute();
111 }
112 }
113 }
114
115 static final class SubSorter extends RecursiveAction {
116 final Sorter left;
117 final Sorter right;
118 final Merger merger;
119 SubSorter(Sorter left, Sorter right, Merger merger) {
120 this.left = left; this.right = right; this.merger = merger;
121 }
122 public void compute() {
123 right.fork();
124 left.compute();
125 right.join();
126 merger.compute();
127 }
128 }
129
130 static final class Merger extends RecursiveAction {
131 final Long[] a; final Long[] w;
132 final int lo; final int ln; final int ro; final int rn; final int wo;
133 Merger next;
134 Merger(Long[] a, Long[] w, int lo, int ln, int ro, int rn, int wo,
135 Merger next) {
136 this.a = a; this.w = w;
137 this.lo = lo; this.ln = ln;
138 this.ro = ro; this.rn = rn;
139 this.wo = wo;
140 this.next = next;
141 }
142
143 /**
144 * Merge left and right by splitting left in half,
145 * and finding index of right closest to split point.
146 * Uses left-spine decomposition to generate all
147 * merge tasks before bottomming out at base case.
148 *
149 */
150 public final void compute() {
151 Merger rights = null;
152 int nleft = ln;
153 int nright = rn;
154 while (nleft > THRESHOLD) { // && nright > (THRESHOLD >>> 3)) {
155 int lh = nleft >>> 1;
156 int splitIndex = lo + lh;
157 Long split = a[splitIndex];
158 int rl = 0;
159 int rh = nright;
160 while (rl < rh) {
161 int mid = (rl + rh) >>> 1;
162 if (split <= a[ro + mid])
163 rh = mid;
164 else
165 rl = mid + 1;
166 }
167 (rights = new Merger(a, w, splitIndex, nleft-lh, ro+rh,
168 nright-rh, wo+lh+rh, rights)).fork();
169 nleft = lh;
170 nright = rh;
171 }
172
173 merge(nleft, nright);
174 if (rights != null)
175 collectRights(rights);
176
177 }
178
179 final void merge(int nleft, int nright) {
180 int l = lo;
181 int lFence = lo + nleft;
182 int r = ro;
183 int rFence = ro + nright;
184 int k = wo;
185 while (l < lFence && r < rFence) {
186 Long al = a[l];
187 Long ar = a[r];
188 Long t;
189 if (al <= ar) { ++l; t = al; } else { ++r; t = ar; }
190 w[k++] = t;
191 }
192 while (l < lFence)
193 w[k++] = a[l++];
194 while (r < rFence)
195 w[k++] = a[r++];
196 }
197
198 static void collectRights(Merger rt) {
199 while (rt != null) {
200 Merger next = rt.next;
201 rt.next = null;
202 if (rt.tryUnfork()) rt.compute(); else rt.join();
203 rt = next;
204 }
205 }
206
207 }
208
209 static void checkSorted(Long[] a) {
210 int n = a.length;
211 for (int i = 0; i < n - 1; i++) {
212 if (a[i] > a[i+1]) {
213 throw new Error("Unsorted at " + i + ": " +
214 a[i] + " / " + a[i+1]);
215 }
216 }
217 }
218
219 static void seqRandomFill(Long[] array, int lo, int hi) {
220 ThreadLocalRandom rng = ThreadLocalRandom.current();
221 for (int i = lo; i < hi; ++i)
222 array[i] = rng.nextLong();
223 }
224
225 static final class RandomFiller extends RecursiveAction {
226 final Long[] array;
227 final int lo, hi;
228 RandomFiller(Long[] array, int lo, int hi) {
229 this.array = array; this.lo = lo; this.hi = hi;
230 }
231 public void compute() {
232 if (hi - lo <= THRESHOLD) {
233 Long[] a = array;
234 ThreadLocalRandom rng = ThreadLocalRandom.current();
235 for (int i = lo; i < hi; ++i)
236 a[i] = rng.nextLong();
237 }
238 else {
239 int mid = (lo + hi) >>> 1;
240 RandomFiller r = new RandomFiller(array, mid, hi);
241 r.fork();
242 (new RandomFiller(array, lo, mid)).compute();
243 r.join();
244 }
245 }
246 }
247
248
249 }