ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ScalarLongSort.java
Revision: 1.14
Committed: Mon Aug 10 03:13:33 2015 UTC (8 years, 8 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +0 -1 lines
Log Message:
delete unwanted blank lines

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.*;
8 import java.util.concurrent.*;
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 pool.shutdown();
82 }
83
84 static final class Sorter extends RecursiveAction {
85 final long[] a;
86 final long[] w;
87 final int origin;
88 final int n;
89 Sorter(long[] a, long[] w, int origin, int n) {
90 this.a = a; this.w = w; this.origin = origin; this.n = n;
91 }
92
93 public void compute() {
94 int l = origin;
95 if (n <= THRESHOLD)
96 Arrays.sort(a, l, l+n);
97 else { // divide in quarters to ensure sorted array in a not w
98 int h = n >>> 1;
99 int q = n >>> 2;
100 int u = h + q;
101 SubSorter rs = new SubSorter
102 (new Sorter(a, w, l+h, q),
103 new Sorter(a, w, l+u, n-u),
104 new Merger(a, w, l+h, q, l+u, n-u, l+h, null));
105 rs.fork();
106 Sorter rl = new Sorter(a, w, l+q, h-q);
107 rl.fork();
108 (new Sorter(a, w, l, q)).compute();
109 rl.join();
110 (new Merger(a, w, l, q, l+q, h-q, l, null)).compute();
111 rs.join();
112 new Merger(w, a, l, h, l+h, n-h, l, null).compute();
113 }
114 }
115 }
116
117 static final class SubSorter extends RecursiveAction {
118 final Sorter left;
119 final Sorter right;
120 final Merger merger;
121 SubSorter(Sorter left, Sorter right, Merger merger) {
122 this.left = left; this.right = right; this.merger = merger;
123 }
124 public void compute() {
125 right.fork();
126 left.compute();
127 right.join();
128 merger.compute();
129 }
130 }
131
132 static final class Merger extends RecursiveAction {
133 final long[] a; final long[] w;
134 final int lo; final int ln; final int ro; final int rn; final int wo;
135 Merger next;
136 Merger(long[] a, long[] w, int lo, int ln, int ro, int rn, int wo,
137 Merger next) {
138 this.a = a; this.w = w;
139 this.lo = lo; this.ln = ln;
140 this.ro = ro; this.rn = rn;
141 this.wo = wo;
142 this.next = next;
143 }
144
145 /**
146 * Merge left and right by splitting left in half,
147 * and finding index of right closest to split point.
148 * Uses left-spine decomposition to generate all
149 * merge tasks before bottomming out at base case.
150 */
151 public final void compute() {
152 Merger rights = null;
153 int nleft = ln;
154 int nright = rn;
155 while (nleft > THRESHOLD) { // && nright > (THRESHOLD >>> 3)) {
156 int lh = nleft >>> 1;
157 int splitIndex = lo + lh;
158 long split = a[splitIndex];
159 int rl = 0;
160 int rh = nright;
161 while (rl < rh) {
162 int mid = (rl + rh) >>> 1;
163 if (split <= a[ro + mid])
164 rh = mid;
165 else
166 rl = mid + 1;
167 }
168 (rights = new Merger(a, w, splitIndex, nleft-lh, ro+rh,
169 nright-rh, wo+lh+rh, rights)).fork();
170 nleft = lh;
171 nright = rh;
172 }
173
174 merge(nleft, nright);
175 if (rights != null)
176 collectRights(rights);
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 }