ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/BoxedLongSort.java
Revision: 1.1
Committed: Sun Sep 19 12:55:36 2010 UTC (13 years, 7 months ago) by dl
Branch: MAIN
Log Message:
Add and update FJ and Queue tests

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     * http://creativecommons.org/licenses/publicdomain
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     }