ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/BoxedLongSort.java
(Generate patch)

Comparing jsr166/src/test/loops/BoxedLongSort.java (file contents):
Revision 1.6 by jsr166, Mon Oct 10 16:59:04 2011 UTC vs.
Revision 1.13 by dl, Sat Sep 12 18:12:20 2015 UTC

# Line 4 | Line 4
4   * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7 import java.util.concurrent.*;
7   import java.util.*;
8 + import java.util.concurrent.*;
9  
10   class BoxedLongSort {
11      static final long NPS = (1000L * 1000 * 1000);
12  
13      static int THRESHOLD;
14 <    static final boolean warmup = true;
14 >    //    static final int THRESHOLD = 64;
15  
16      public static void main(String[] args) throws Exception {
17          int procs = 0;
18          int n = 1 << 22;
19 <        int reps = 20;
19 >        int reps = 30;
20          int sreps = 2;
21          try {
22              if (args.length > 0)
# Line 30 | Line 30 | class BoxedLongSort {
30              System.out.println("Usage: java BoxedLongSort threads n reps");
31              return;
32          }
33 <        ForkJoinPool pool = (procs == 0) ? new ForkJoinPool() :
34 <            new ForkJoinPool(procs);
33 >        if (procs == 0)
34 >            procs = Runtime.getRuntime().availableProcessors();
35  
36 +        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          Long[] a = new Long[n];
48 <        seqRandomFill(a, 0, n);
49 <
50 <        if (warmup) {
51 <            System.out.printf("Sorting %d longs, %d replications\n", n, 1);
52 <            Collections.shuffle(Arrays.asList(a));
53 <            long last = System.nanoTime();
54 <            java.util.Arrays.sort(a);
55 <            double elapsed = (double)(System.nanoTime() - last) / NPS;
56 <            System.out.printf("Arrays.sort   time:  %7.3f\n", elapsed);
57 <            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();
48 >        //        ForkJoinPool pool = new ForkJoinPool(procs);
49 >        ForkJoinPool pool = ForkJoinPool.commonPool();
50 >        seqTest(a, numbers, pool, 1);
51 >        System.out.println(pool);
52 >        parTest(a, numbers, pool, reps);
53 >        System.out.println(pool);
54 >        seqTest(a, numbers, pool, 2);
55 >        System.out.println(pool);
56 >        pool.shutdown();
57 >    }
58  
59 +    static void seqTest(Long[] a, Long[] numbers, ForkJoinPool pool, int reps) {
60 +        int n = numbers.length;
61          System.out.printf("Sorting %d longs, %d replications\n", n, reps);
62 +        long start = System.nanoTime();
63          for (int i = 0; i < reps; ++i) {
64 <            Collections.shuffle(Arrays.asList(a));
65 <            //            pool.invoke(new RandomFiller(a, 0, n));
64 >            new RandomRepacker(numbers, a, 0, n, n).invoke();
65 >            //            pool.invoke(new TaskChecker());
66              long last = System.nanoTime();
67 <            pool.invoke(new Sorter(a, new Long[n], 0, n));
68 <            double elapsed = (double)(System.nanoTime() - last) / NPS;
69 <            System.out.printf("Parallel sort time: %7.3f\n", elapsed);
67 >            //            quickSort(a, 0, n-1);
68 >            java.util.Arrays.sort(a);
69 >            long now = System.nanoTime();
70 >            double total = (double)(now - start) / NPS;
71 >            double elapsed = (double)(now - last) / NPS;
72 >            System.out.printf("Arrays.sort   time:  %7.3f total %9.3f\n",
73 >                              elapsed, total);
74              if (i == 0)
75                  checkSorted(a);
76          }
77 <        System.out.println(pool);
77 >    }
78  
79 <        System.out.printf("Sorting %d longs, %d replications\n", n, sreps);
80 <        for (int i = 0; i < sreps; ++i) {
81 <            Collections.shuffle(Arrays.asList(a));
82 <            //            pool.invoke(new RandomFiller(a, 0, n));
79 >    static void parTest(Long[] a, Long[] numbers, ForkJoinPool pool, int reps) throws Exception {
80 >        int n = numbers.length;
81 >        Long[] w = new Long[n];
82 >        System.out.printf("Sorting %d longs, %d replications\n", n, reps);
83 >        long start = System.nanoTime();
84 >        for (int i = 0; i < reps; ++i) {
85 >            //            Arrays.fill(w, 0, n, null);
86 >            new RandomRepacker(numbers, a, 0, n, n).invoke();
87 >            //            Thread.sleep(500);
88 >            //            pool.invoke(new TaskChecker());
89              long last = System.nanoTime();
90 <            java.util.Arrays.sort(a);
91 <            double elapsed = (double)(System.nanoTime() - last) / NPS;
92 <            System.out.printf("Arrays.sort   time:  %7.3f\n", elapsed);
90 >            new Sorter(a, w, 0, n).invoke();
91 >            long now = System.nanoTime();
92 >            //            pool.invoke(new TaskChecker());
93 >            double total = (double)(now - start) / NPS;
94 >            double elapsed = (double)(now - last) / NPS;
95 >            System.out.printf("Parallel sort time:  %7.3f total %9.3f\n",
96 >                              elapsed, total);
97              if (i == 0)
98                  checkSorted(a);
99          }
78        System.out.println(pool);
79        pool.shutdown();
100      }
101  
102      static final class Sorter extends RecursiveAction {
# Line 90 | Line 110 | class BoxedLongSort {
110  
111          public void compute() {
112              int l = origin;
113 <            if (n <= THRESHOLD)
114 <                Arrays.sort(a, l, l+n);
113 >            if (n <= THRESHOLD) {
114 >                //                Arrays.sort(a, l, l+n);
115 >                quickSort(a, l, l+n-1);
116 >            }
117              else { // divide in quarters to ensure sorted array in a not w
118                  int h = n >>> 1;
119                  int q = n >>> 2;
# Line 145 | Line 167 | class BoxedLongSort {
167           * and finding index of right closest to split point.
168           * Uses left-spine decomposition to generate all
169           * merge tasks before bottomming out at base case.
148         *
170           */
171          public final void compute() {
172              Merger rights = null;
173 <            int nleft = ln;
174 <            int nright = rn;
175 <            while (nleft > THRESHOLD) { //  && nright > (THRESHOLD >>> 3)) {
176 <                int lh = nleft >>> 1;
177 <                int splitIndex = lo + lh;
178 <                Long split = a[splitIndex];
173 >            Long[] a = this.a;
174 >            Long[] w = this.w;
175 >            int ln = this.ln;
176 >            int rn = this.rn;
177 >            int l = this.lo;
178 >            int r = this.ro;
179 >            int k = this.wo;
180 >            while (ln > THRESHOLD && rn > 4) {
181 >                int lh = ln >>> 1;
182 >                int lm = l + lh;
183 >                Long split = a[lm];
184 >                long ls = split.longValue();
185                  int rl = 0;
186 <                int rh = nright;
186 >                int rh = rn;
187                  while (rl < rh) {
188 <                    int mid = (rl + rh) >>> 1;
189 <                    if (split <= a[ro + mid])
190 <                        rh = mid;
188 >                    int rm = (rl + rh) >>> 1;
189 >                    if (ls <= a[r + rm].longValue())
190 >                        rh = rm;
191                      else
192 <                        rl = mid + 1;
192 >                        rl = rm + 1;
193 >                }
194 >                (rights = new Merger(a, w, lm, ln-lh, r+rh, rn-rh, k+lh+rh, rights)).fork();
195 >                rn = rh;
196 >                ln = lh;
197 >            }
198 >
199 >            int lFence = l + ln;
200 >            int rFence = r + rn;
201 >            for (Long t;;) {
202 >                if (l < lFence) {
203 >                    Long al = a[l], ar;
204 >                    if (r >= rFence ||
205 >                        al.longValue() <= (ar = a[r]).longValue()) {
206 >                        ++l; t = al;
207 >                    }
208 >                    else {
209 >                        ++r; t = ar;
210 >                    }
211                  }
212 <                (rights = new Merger(a, w, splitIndex, nleft-lh, ro+rh,
213 <                                     nright-rh, wo+lh+rh, rights)).fork();
214 <                nleft = lh;
215 <                nright = rh;
212 >                else if (r < rFence)
213 >                    t = a[r++];
214 >                else
215 >                    break;
216 >                w[k++] = t;
217              }
218  
219 <            merge(nleft, nright);
219 >            //            merge(nleft, nright);
220              if (rights != null)
221                  collectRights(rights);
176
222          }
223  
224          final void merge(int nleft, int nright) {
# Line 245 | Line 290 | class BoxedLongSort {
290          }
291      }
292  
293 +    static final class RandomRepacker extends RecursiveAction {
294 +        final Long[] src;
295 +        final Long[] dst;
296 +        final int lo, hi, size;
297 +        RandomRepacker(Long[] src, Long[] dst,
298 +                       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 +
303 +        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   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines