ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/BoxedLongSort.java
Revision: 1.9
Committed: Sun Oct 21 06:14:12 2012 UTC (11 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +0 -1 lines
Log Message:
delete trailing empty lines of javadoc

File Contents

# User Rev Content
1 dl 1.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 jsr166 1.5 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
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 dl 1.7 // static final int THRESHOLD = 64;
15 dl 1.1
16 jsr166 1.6 public static void main(String[] args) throws Exception {
17 dl 1.1 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 dl 1.7 if (procs == 0)
34     procs = Runtime.getRuntime().availableProcessors();
35 jsr166 1.2
36 dl 1.7 THRESHOLD = ((n + 7) >>> 3) / procs;
37     // THRESHOLD = ((n + 15) >>> 4) / procs;
38     // THRESHOLD = ((n + 31) >>> 5) / procs;
39     if (THRESHOLD < 64)
40     THRESHOLD = 64;
41    
42     System.out.println("Threshold = " + THRESHOLD);
43    
44     Long[] numbers = new Long[n];
45     for (int i = 0; i < n; ++i)
46     numbers[i] = Long.valueOf(i);
47 dl 1.1 Long[] a = new Long[n];
48 dl 1.7 ForkJoinPool pool = new ForkJoinPool(procs);
49     seqTest(a, numbers, pool, 1);
50     System.out.println(pool);
51     parTest(a, numbers, pool, reps);
52     System.out.println(pool);
53     seqTest(a, numbers, pool, 2);
54     System.out.println(pool);
55     pool.shutdown();
56     }
57 dl 1.1
58 dl 1.7 static void seqTest(Long[] a, Long[] numbers, ForkJoinPool pool, int reps) {
59     int n = numbers.length;
60 dl 1.1 System.out.printf("Sorting %d longs, %d replications\n", n, reps);
61 dl 1.7 long start = System.nanoTime();
62 dl 1.1 for (int i = 0; i < reps; ++i) {
63 dl 1.7 pool.invoke(new RandomRepacker(numbers, a, 0, n, n));
64     // pool.invoke(new TaskChecker());
65 dl 1.1 long last = System.nanoTime();
66 dl 1.7 // quickSort(a, 0, n-1);
67     java.util.Arrays.sort(a);
68     long now = System.nanoTime();
69     double total = (double)(now - start) / NPS;
70     double elapsed = (double)(now - last) / NPS;
71 jsr166 1.8 System.out.printf("Arrays.sort time: %7.3f total %9.3f\n",
72 dl 1.7 elapsed, total);
73 dl 1.1 if (i == 0)
74     checkSorted(a);
75     }
76 dl 1.7 }
77 dl 1.1
78 dl 1.7 static void parTest(Long[] a, Long[] numbers, ForkJoinPool pool, int reps) {
79     int n = numbers.length;
80     Long[] w = new Long[n];
81     System.out.printf("Sorting %d longs, %d replications\n", n, reps);
82     long start = System.nanoTime();
83     for (int i = 0; i < reps; ++i) {
84     // Arrays.fill(w, 0, n, null);
85     pool.invoke(new RandomRepacker(numbers, a, 0, n, n));
86     // pool.invoke(new TaskChecker());
87 dl 1.1 long last = System.nanoTime();
88 dl 1.7 pool.invoke(new Sorter(a, w, 0, n));
89     long now = System.nanoTime();
90     // pool.invoke(new TaskChecker());
91     double total = (double)(now - start) / NPS;
92     double elapsed = (double)(now - last) / NPS;
93 jsr166 1.8 System.out.printf("Parallel sort time: %7.3f total %9.3f\n",
94 dl 1.7 elapsed, total);
95 dl 1.1 if (i == 0)
96     checkSorted(a);
97     }
98     }
99    
100     static final class Sorter extends RecursiveAction {
101 jsr166 1.2 final Long[] a;
102 dl 1.1 final Long[] w;
103 jsr166 1.2 final int origin;
104 dl 1.1 final int n;
105     Sorter(Long[] a, Long[] w, int origin, int n) {
106     this.a = a; this.w = w; this.origin = origin; this.n = n;
107     }
108    
109 jsr166 1.3 public void compute() {
110 dl 1.1 int l = origin;
111 dl 1.7 if (n <= THRESHOLD) {
112     // Arrays.sort(a, l, l+n);
113     quickSort(a, l, l+n-1);
114     }
115 dl 1.1 else { // divide in quarters to ensure sorted array in a not w
116     int h = n >>> 1;
117     int q = n >>> 2;
118     int u = h + q;
119     SubSorter rs = new SubSorter
120     (new Sorter(a, w, l+h, q),
121     new Sorter(a, w, l+u, n-u),
122     new Merger(a, w, l+h, q, l+u, n-u, l+h, null));
123     rs.fork();
124     Sorter rl = new Sorter(a, w, l+q, h-q);
125     rl.fork();
126     (new Sorter(a, w, l, q)).compute();
127     rl.join();
128     (new Merger(a, w, l, q, l+q, h-q, l, null)).compute();
129     rs.join();
130     new Merger(w, a, l, h, l+h, n-h, l, null).compute();
131     }
132     }
133     }
134 jsr166 1.2
135 dl 1.1 static final class SubSorter extends RecursiveAction {
136     final Sorter left;
137     final Sorter right;
138     final Merger merger;
139     SubSorter(Sorter left, Sorter right, Merger merger) {
140     this.left = left; this.right = right; this.merger = merger;
141     }
142     public void compute() {
143     right.fork();
144     left.compute();
145     right.join();
146     merger.compute();
147     }
148     }
149    
150     static final class Merger extends RecursiveAction {
151     final Long[] a; final Long[] w;
152     final int lo; final int ln; final int ro; final int rn; final int wo;
153     Merger next;
154     Merger(Long[] a, Long[] w, int lo, int ln, int ro, int rn, int wo,
155     Merger next) {
156     this.a = a; this.w = w;
157     this.lo = lo; this.ln = ln;
158     this.ro = ro; this.rn = rn;
159     this.wo = wo;
160     this.next = next;
161     }
162    
163     /**
164     * Merge left and right by splitting left in half,
165     * and finding index of right closest to split point.
166     * Uses left-spine decomposition to generate all
167     * merge tasks before bottomming out at base case.
168     */
169     public final void compute() {
170     Merger rights = null;
171 dl 1.7 Long[] a = this.a;
172     Long[] w = this.w;
173     int ln = this.ln;
174     int rn = this.rn;
175     int l = this.lo;
176     int r = this.ro;
177     int k = this.wo;
178     while (ln > THRESHOLD && rn > 4) {
179     int lh = ln >>> 1;
180     int lm = l + lh;
181     Long split = a[lm];
182     long ls = split.longValue();
183 dl 1.1 int rl = 0;
184 dl 1.7 int rh = rn;
185 dl 1.1 while (rl < rh) {
186 dl 1.7 int rm = (rl + rh) >>> 1;
187     if (ls <= a[r + rm].longValue())
188     rh = rm;
189 dl 1.1 else
190 dl 1.7 rl = rm + 1;
191 dl 1.1 }
192 dl 1.7 (rights = new Merger(a, w, lm, ln-lh, r+rh, rn-rh, k+lh+rh, rights)).fork();
193     rn = rh;
194     ln = lh;
195 dl 1.1 }
196 jsr166 1.2
197 dl 1.7 int lFence = l + ln;
198     int rFence = r + rn;
199     for (Long t;;) {
200     if (l < lFence) {
201     Long al = a[l], ar;
202     if (r >= rFence ||
203     al.longValue() <= (ar = a[r]).longValue()) {
204 jsr166 1.8 ++l; t = al;
205     }
206     else {
207     ++r; t = ar;
208 dl 1.7 }
209     }
210     else if (r < rFence)
211     t = a[r++];
212 jsr166 1.8 else
213 dl 1.7 break;
214     w[k++] = t;
215     }
216    
217     // merge(nleft, nright);
218 jsr166 1.2 if (rights != null)
219 dl 1.1 collectRights(rights);
220 jsr166 1.2
221 dl 1.1 }
222    
223     final void merge(int nleft, int nright) {
224     int l = lo;
225     int lFence = lo + nleft;
226     int r = ro;
227     int rFence = ro + nright;
228     int k = wo;
229     while (l < lFence && r < rFence) {
230     Long al = a[l];
231     Long ar = a[r];
232     Long t;
233     if (al <= ar) { ++l; t = al; } else { ++r; t = ar; }
234     w[k++] = t;
235     }
236     while (l < lFence)
237     w[k++] = a[l++];
238     while (r < rFence)
239     w[k++] = a[r++];
240     }
241    
242     static void collectRights(Merger rt) {
243     while (rt != null) {
244     Merger next = rt.next;
245     rt.next = null;
246     if (rt.tryUnfork()) rt.compute(); else rt.join();
247     rt = next;
248     }
249     }
250    
251     }
252    
253 jsr166 1.6 static void checkSorted(Long[] a) {
254 dl 1.1 int n = a.length;
255     for (int i = 0; i < n - 1; i++) {
256     if (a[i] > a[i+1]) {
257 jsr166 1.2 throw new Error("Unsorted at " + i + ": " +
258 dl 1.1 a[i] + " / " + a[i+1]);
259     }
260     }
261     }
262    
263     static void seqRandomFill(Long[] array, int lo, int hi) {
264     ThreadLocalRandom rng = ThreadLocalRandom.current();
265     for (int i = lo; i < hi; ++i)
266     array[i] = rng.nextLong();
267     }
268    
269     static final class RandomFiller extends RecursiveAction {
270     final Long[] array;
271     final int lo, hi;
272     RandomFiller(Long[] array, int lo, int hi) {
273     this.array = array; this.lo = lo; this.hi = hi;
274     }
275     public void compute() {
276     if (hi - lo <= THRESHOLD) {
277     Long[] a = array;
278     ThreadLocalRandom rng = ThreadLocalRandom.current();
279     for (int i = lo; i < hi; ++i)
280     a[i] = rng.nextLong();
281     }
282     else {
283     int mid = (lo + hi) >>> 1;
284     RandomFiller r = new RandomFiller(array, mid, hi);
285     r.fork();
286     (new RandomFiller(array, lo, mid)).compute();
287     r.join();
288     }
289     }
290     }
291    
292    
293 dl 1.7 static final class RandomRepacker extends RecursiveAction {
294     final Long[] src;
295     final Long[] dst;
296     final int lo, hi, size;
297 jsr166 1.8 RandomRepacker(Long[] src, Long[] dst,
298 dl 1.7 int lo, int hi, int size) {
299     this.src = src; this.dst = dst;
300     this.lo = lo; this.hi = hi; this.size = size;
301     }
302 jsr166 1.8
303 dl 1.7 public final void compute() {
304     Long[] s = src;
305     Long[] d = dst;
306     int l = lo, h = hi, n = size;
307     if (h - l > THRESHOLD) {
308     int m = (l + h) >>> 1;
309     invokeAll(new RandomRepacker(s, d, l, m, n),
310     new RandomRepacker(s, d, m, h, n));
311     }
312     else {
313     ThreadLocalRandom rng = ThreadLocalRandom.current();
314     for (int i = l; i < h; ++i)
315     d[i] = s[rng.nextInt(n)];
316     }
317     }
318     }
319    
320     static final int INSERTION_SORT_THRESHOLD = 8;
321    
322     static void quickSort(Long[] a, int lo, int hi) {
323     for (;;) {
324     if (hi - lo <= INSERTION_SORT_THRESHOLD) {
325     for (int i = lo + 1; i <= hi; i++) {
326     Long t = a[i];
327     long tv = t.longValue();
328     int j = i - 1;
329     while (j >= lo && tv < a[j].longValue()) {
330     a[j+1] = a[j];
331     --j;
332     }
333     a[j+1] = t;
334     }
335     return;
336     }
337    
338     int mid = (lo + hi) >>> 1;
339     if (a[lo].longValue() > a[mid].longValue()) {
340     Long t = a[lo]; a[lo] = a[mid]; a[mid] = t;
341     }
342     if (a[mid].longValue() > a[hi].longValue()) {
343     Long t = a[mid]; a[mid] = a[hi]; a[hi] = t;
344     if (a[lo].longValue() > a[mid].longValue()) {
345     Long u = a[lo]; a[lo] = a[mid]; a[mid] = u;
346     }
347     }
348    
349     long pivot = a[mid].longValue();
350     int left = lo+1;
351     int right = hi-1;
352     for (;;) {
353     while (pivot < a[right].longValue())
354     --right;
355     while (left < right && pivot >= a[left].longValue())
356     ++left;
357     if (left < right) {
358     Long t = a[left]; a[left] = a[right]; a[right] = t;
359     --right;
360     }
361     else break;
362     }
363    
364     if (left - lo <= hi - right) {
365     quickSort(a, lo, left);
366     lo = left + 1;
367     }
368     else {
369     quickSort(a, right, hi);
370     hi = left;
371     }
372     }
373     }
374    
375 dl 1.1 }