ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/BoxedLongSort.java
Revision: 1.7
Committed: Mon Apr 9 13:18:06 2012 UTC (12 years, 1 month ago) by dl
Branch: MAIN
Changes since 1.6: +179 -52 lines
Log Message:
Add tests/demos for CountedCompleters

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     System.out.printf("Arrays.sort time: %7.3f total %9.3f\n",
72     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     System.out.printf("Parallel sort time: %7.3f total %9.3f\n",
94     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 jsr166 1.2 *
169 dl 1.1 */
170     public final void compute() {
171     Merger rights = null;
172 dl 1.7 Long[] a = this.a;
173     Long[] w = this.w;
174     int ln = this.ln;
175     int rn = this.rn;
176     int l = this.lo;
177     int r = this.ro;
178     int k = this.wo;
179     while (ln > THRESHOLD && rn > 4) {
180     int lh = ln >>> 1;
181     int lm = l + lh;
182     Long split = a[lm];
183     long ls = split.longValue();
184 dl 1.1 int rl = 0;
185 dl 1.7 int rh = rn;
186 dl 1.1 while (rl < rh) {
187 dl 1.7 int rm = (rl + rh) >>> 1;
188     if (ls <= a[r + rm].longValue())
189     rh = rm;
190 dl 1.1 else
191 dl 1.7 rl = rm + 1;
192 dl 1.1 }
193 dl 1.7 (rights = new Merger(a, w, lm, ln-lh, r+rh, rn-rh, k+lh+rh, rights)).fork();
194     rn = rh;
195     ln = lh;
196 dl 1.1 }
197 jsr166 1.2
198 dl 1.7 int lFence = l + ln;
199     int rFence = r + rn;
200     for (Long t;;) {
201     if (l < lFence) {
202     Long al = a[l], ar;
203     if (r >= rFence ||
204     al.longValue() <= (ar = a[r]).longValue()) {
205     ++l; t = al;
206     }
207     else {
208     ++r; t = ar;
209     }
210     }
211     else if (r < rFence)
212     t = a[r++];
213     else
214     break;
215     w[k++] = t;
216     }
217    
218     // merge(nleft, nright);
219 jsr166 1.2 if (rights != null)
220 dl 1.1 collectRights(rights);
221 jsr166 1.2
222 dl 1.1 }
223    
224     final void merge(int nleft, int nright) {
225     int l = lo;
226     int lFence = lo + nleft;
227     int r = ro;
228     int rFence = ro + nright;
229     int k = wo;
230     while (l < lFence && r < rFence) {
231     Long al = a[l];
232     Long ar = a[r];
233     Long t;
234     if (al <= ar) { ++l; t = al; } else { ++r; t = ar; }
235     w[k++] = t;
236     }
237     while (l < lFence)
238     w[k++] = a[l++];
239     while (r < rFence)
240     w[k++] = a[r++];
241     }
242    
243     static void collectRights(Merger rt) {
244     while (rt != null) {
245     Merger next = rt.next;
246     rt.next = null;
247     if (rt.tryUnfork()) rt.compute(); else rt.join();
248     rt = next;
249     }
250     }
251    
252     }
253    
254 jsr166 1.6 static void checkSorted(Long[] a) {
255 dl 1.1 int n = a.length;
256     for (int i = 0; i < n - 1; i++) {
257     if (a[i] > a[i+1]) {
258 jsr166 1.2 throw new Error("Unsorted at " + i + ": " +
259 dl 1.1 a[i] + " / " + a[i+1]);
260     }
261     }
262     }
263    
264     static void seqRandomFill(Long[] array, int lo, int hi) {
265     ThreadLocalRandom rng = ThreadLocalRandom.current();
266     for (int i = lo; i < hi; ++i)
267     array[i] = rng.nextLong();
268     }
269    
270     static final class RandomFiller extends RecursiveAction {
271     final Long[] array;
272     final int lo, hi;
273     RandomFiller(Long[] array, int lo, int hi) {
274     this.array = array; this.lo = lo; this.hi = hi;
275     }
276     public void compute() {
277     if (hi - lo <= THRESHOLD) {
278     Long[] a = array;
279     ThreadLocalRandom rng = ThreadLocalRandom.current();
280     for (int i = lo; i < hi; ++i)
281     a[i] = rng.nextLong();
282     }
283     else {
284     int mid = (lo + hi) >>> 1;
285     RandomFiller r = new RandomFiller(array, mid, hi);
286     r.fork();
287     (new RandomFiller(array, lo, mid)).compute();
288     r.join();
289     }
290     }
291     }
292    
293    
294 dl 1.7 static final class RandomRepacker extends RecursiveAction {
295     final Long[] src;
296     final Long[] dst;
297     final int lo, hi, size;
298     RandomRepacker(Long[] src, Long[] dst,
299     int lo, int hi, int size) {
300     this.src = src; this.dst = dst;
301     this.lo = lo; this.hi = hi; this.size = size;
302     }
303    
304     public final void compute() {
305     Long[] s = src;
306     Long[] d = dst;
307     int l = lo, h = hi, n = size;
308     if (h - l > THRESHOLD) {
309     int m = (l + h) >>> 1;
310     invokeAll(new RandomRepacker(s, d, l, m, n),
311     new RandomRepacker(s, d, m, h, n));
312     }
313     else {
314     ThreadLocalRandom rng = ThreadLocalRandom.current();
315     for (int i = l; i < h; ++i)
316     d[i] = s[rng.nextInt(n)];
317     }
318     }
319     }
320    
321     static final int INSERTION_SORT_THRESHOLD = 8;
322    
323     static void quickSort(Long[] a, int lo, int hi) {
324     for (;;) {
325     if (hi - lo <= INSERTION_SORT_THRESHOLD) {
326     for (int i = lo + 1; i <= hi; i++) {
327     Long t = a[i];
328     long tv = t.longValue();
329     int j = i - 1;
330     while (j >= lo && tv < a[j].longValue()) {
331     a[j+1] = a[j];
332     --j;
333     }
334     a[j+1] = t;
335     }
336     return;
337     }
338    
339     int mid = (lo + hi) >>> 1;
340     if (a[lo].longValue() > a[mid].longValue()) {
341     Long t = a[lo]; a[lo] = a[mid]; a[mid] = t;
342     }
343     if (a[mid].longValue() > a[hi].longValue()) {
344     Long t = a[mid]; a[mid] = a[hi]; a[hi] = t;
345     if (a[lo].longValue() > a[mid].longValue()) {
346     Long u = a[lo]; a[lo] = a[mid]; a[mid] = u;
347     }
348     }
349    
350     long pivot = a[mid].longValue();
351     int left = lo+1;
352     int right = hi-1;
353     for (;;) {
354     while (pivot < a[right].longValue())
355     --right;
356     while (left < right && pivot >= a[left].longValue())
357     ++left;
358     if (left < right) {
359     Long t = a[left]; a[left] = a[right]; a[right] = t;
360     --right;
361     }
362     else break;
363     }
364    
365     if (left - lo <= hi - right) {
366     quickSort(a, lo, left);
367     lo = left + 1;
368     }
369     else {
370     quickSort(a, right, hi);
371     hi = left;
372     }
373     }
374     }
375    
376 dl 1.1 }