Skip to content

Commit eb95b47

Browse files
committed
Began to work on the parallel radix sort.
1 parent d49dfdc commit eb95b47

File tree

1 file changed

+113
-22
lines changed

1 file changed

+113
-22
lines changed

src/main/java/com/github/coderodde/util/ParallelRadixSort.java

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,29 @@ public final class ParallelRadixSort {
6464
*/
6565
private static final int MINIMUM_THREAD_WORKLOAD = 4001;
6666

67-
private static int insertionSortThreshold = DEFAULT_INSERTION_SORT_THRESHOLD;
68-
private static int mergesortThreshold = DEFAULT_MERGESORT_THRESHOLD;
69-
private static int threadWorkload = DEFAULT_THREAD_THRESHOLD;
67+
/**
68+
* The current actual threshold for the insertion sort.
69+
*/
70+
private static volatile int insertionSortThreshold =
71+
DEFAULT_INSERTION_SORT_THRESHOLD;
72+
73+
/**
74+
* The current actual threshold for the mergesort.
75+
*/
76+
private static volatile int mergesortThreshold =
77+
DEFAULT_MERGESORT_THRESHOLD;
7078

79+
/**
80+
* The current actual minimum thread workload in elements.
81+
*/
82+
private static volatile int minimumThreadWorkload =
83+
DEFAULT_THREAD_THRESHOLD;
84+
85+
/**
86+
* Sets the current insertion sort threshold.
87+
*
88+
* @param newInsertionSortThreshold the new insertion sort threshold.
89+
*/
7190
public static void setInsertionSortThreshold(
7291
int newInsertionSortThreshold) {
7392
insertionSortThreshold =
@@ -76,18 +95,28 @@ public static void setInsertionSortThreshold(
7695
MINIMUM_INSERTION_SORT_THRESHOLD);
7796
}
7897

98+
/**
99+
* Sets the current mergesort threshold.
100+
*
101+
* @param newMergesortThreshold the new mergesort threshold.
102+
*/
79103
public static void setMergesortThreshold(int newMergesortThreshold) {
80104
mergesortThreshold =
81105
Math.max(
82106
newMergesortThreshold,
83107
MINIMUM_MERGESORT_THRESHOLD);
84108
}
85109

86-
public static void setThreadWorkload(int newThreadWorkload) {
87-
threadWorkload =
110+
/**
111+
* Sets the current minimum thread workload.
112+
*
113+
* @param newMinimumThreadWorkload the new minimum thread workload.
114+
*/
115+
public static void setMinimumThreadWorkload(int newMinimumThreadWorkload) {
116+
minimumThreadWorkload =
88117
Math.max(
89118
MINIMUM_THREAD_WORKLOAD,
90-
newThreadWorkload);
119+
newMinimumThreadWorkload);
91120
}
92121

93122
public static void parallelSort(int[] array) {
@@ -125,7 +154,7 @@ public static void parallelSort(int[] array, int fromIndex, int toIndex) {
125154
int threads =
126155
Math.min(
127156
Runtime.getRuntime().availableProcessors(),
128-
rangeLength / threadWorkload);
157+
rangeLength / minimumThreadWorkload);
129158

130159
threads = Math.max(threads, 1);
131160

@@ -159,6 +188,8 @@ private static void parallelRadixSortImpl(
159188

160189
return;
161190
}
191+
192+
162193
}
163194

164195
private static void rangeCheck(
@@ -201,18 +232,6 @@ private static void radixSortImpl(int[] source,
201232
int targetFromIndex,
202233
int rangeLength,
203234
int recursionDepth) {
204-
//
205-
// if (rangeLength <= mergesortThreshold) {
206-
// mergesort(
207-
// source,
208-
// target,
209-
// sourceFromIndex,
210-
// targetFromIndex,
211-
// rangeLength,
212-
// recursionDepth);
213-
//
214-
// return;
215-
// }
216235

217236
int[] bucketSizeMap = new int[BUCKETS];
218237
int[] startIndexMap = new int[BUCKETS];
@@ -229,15 +248,13 @@ private static void radixSortImpl(int[] source,
229248
bucketSizeMap[bucketIndex]++;
230249
}
231250

232-
//
233251
// Compute starting indices for buckets in the target array. This is
234252
// actually just an accumulated array of bucketSizeMap, such that
235253
// startIndexMap[0] = 0, startIndexMap[1] = bucketSizeMap[0], ...,
236254
// startIndexMap[BUCKETS - 1] = bucketSizeMap[0] + bucketSizeMap[1] +
237255
// ... + bucketSizeMap[BUCKETS - 2].
238256
for (int i = 1; i != BUCKETS; i++) {
239-
startIndexMap[i] = startIndexMap[i - 1]
240-
+ bucketSizeMap[i - 1];
257+
startIndexMap[i] = startIndexMap[i - 1] + bucketSizeMap[i - 1];
241258
}
242259

243260
// Insert each element to its own bucket:
@@ -448,4 +465,78 @@ static int getBucketIndex(int element, int recursionDepth) {
448465
* BITS_PER_BYTE))
449466
& EXTRACT_BYTE_MASK;
450467
}
468+
469+
private static final class BucketSizeCounterThread extends Thread {
470+
471+
private final int[] localBucketSizeMap = new int[BUCKETS];
472+
private final int[] array;
473+
private final int fromIndex;
474+
private final int toIndex;
475+
private final int recursionDepth;
476+
477+
BucketSizeCounterThread(int[] array,
478+
int fromIndex,
479+
int toIndex,
480+
int recursionDepth) {
481+
482+
this.array = array;
483+
this.fromIndex = fromIndex;
484+
this.toIndex = toIndex;
485+
this.recursionDepth = recursionDepth;
486+
}
487+
488+
@Override
489+
public void run() {
490+
for (int i = fromIndex; i != toIndex; i++) {
491+
localBucketSizeMap[getBucketIndex(array[i], recursionDepth)]++;
492+
}
493+
}
494+
495+
int[] getLocalBucketSizeMap() {
496+
return localBucketSizeMap;
497+
}
498+
}
499+
500+
private static final class BucketInserterThread extends Thread {
501+
502+
private final int[] source;
503+
private final int[] target;
504+
private final int sourceFromIndex;
505+
private final int targetFromIndex;
506+
private final int[] startIndexMap;
507+
private final int[] processedMap;
508+
private final int rangeLength;
509+
private final int recursionDepth;
510+
511+
BucketInserterThread(int[] source,
512+
int[] target,
513+
int sourceFromIndex,
514+
int targetFromIndex,
515+
int[] startIndexMap,
516+
int[] processedMap,
517+
int rangeLength,
518+
int recursionDepth) {
519+
this.source = source;
520+
this.target = target;
521+
this.sourceFromIndex = sourceFromIndex;
522+
this.targetFromIndex = targetFromIndex;
523+
this.startIndexMap = startIndexMap;
524+
this.processedMap = processedMap;
525+
this.rangeLength = rangeLength;
526+
this.recursionDepth = recursionDepth;
527+
}
528+
529+
@Override
530+
public void run() {
531+
int sourceToIndex = sourceFromIndex + rangeLength;
532+
533+
for (int i = sourceFromIndex; i != sourceToIndex; i++) {
534+
int datum = source[i];
535+
int bucketKey = getBucketIndex(datum, recursionDepth);
536+
537+
target[targetFromIndex + startIndexMap[bucketKey] +
538+
processedMap[bucketKey]++] = datum;
539+
}
540+
}
541+
}
451542
}

0 commit comments

Comments
 (0)