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

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