University stuff.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MultiRadixPar.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import java.util.*;
  2. import java.util.concurrent.CyclicBarrier;
  3. /***********************************************************
  4. * Oblig 3 - sekvensiell kode, INF2440 v2017.
  5. * Ifi, Uio, Arne Maus
  6. * for store verdier av n > 100 m, kjør (f.eks):
  7. * >java -Xmx16000m MultiRadix 1000000000
  8. ************************************************************/
  9. class MultiRadixPar implements Sorter {
  10. int n;
  11. int [] a;
  12. final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best
  13. int nThreads = Math.min(
  14. Runtime.getRuntime().availableProcessors(),
  15. 16);
  16. public int[] sort(int[] arr) {
  17. return radixMulti(arr);
  18. }
  19. class PartAWorker implements Runnable {
  20. int[] a;
  21. int start;
  22. int end;
  23. int biggest;
  24. PartAWorker(int[] a, int start, int end) {
  25. this.a = a;
  26. this.start = start;
  27. this.end = end;
  28. this.biggest = a[start];
  29. }
  30. public void run() {
  31. for (int i = start + 1; i < end; ++i) {
  32. if (a[i] > biggest)
  33. biggest = a[i];
  34. }
  35. }
  36. }
  37. int [] radixMulti(int [] a) {
  38. long tt = System.nanoTime();
  39. // 1-5 digit radixSort of : a[]
  40. int max = a[0], numBit = 2, numDigits, n =a.length;
  41. int [] bit ;
  42. // a) finn max verdi i a[]
  43. int d = a.length / nThreads;
  44. Thread[] threads = new Thread[nThreads];
  45. PartAWorker[] workers = new PartAWorker[nThreads];
  46. for (int i = 0; i < nThreads; ++i) {
  47. PartAWorker w = workers[i] = new PartAWorker(
  48. a, d * i, i == nThreads - 1 ? a.length : d * (i + 1));
  49. Thread t = threads[i] = new Thread(w);
  50. t.start();
  51. }
  52. for (Thread t: threads) { try { t.join(); } catch (InterruptedException ex) {} }
  53. max = workers[0].biggest;
  54. for (int i = 1; i < nThreads; ++i) {
  55. if (workers[i].biggest > max)
  56. max = workers[i].biggest;
  57. }
  58. while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max
  59. // bestem antall bit i numBits sifre
  60. numDigits = Math.max(1, numBit/NUM_BIT);
  61. bit = new int[numDigits];
  62. int rest = (numBit%numDigits), sum =0;;
  63. // fordel bitene vi skal sortere paa jevnt
  64. for (int i = 0; i < bit.length; i++){
  65. bit[i] = numBit/numDigits;
  66. if ( rest-- > 0) bit[i]++;
  67. }
  68. int[] t=a, b = new int [n];
  69. for (int i =0; i < bit.length; i++) {
  70. radixSort( a,b,bit[i],sum ); // i-te siffer fra a[] til b[]
  71. sum += bit[i];
  72. // swap arrays (pointers only)
  73. t = a;
  74. a = b;
  75. b = t;
  76. }
  77. if (bit.length%2 != 0 ) {
  78. // et odde antall sifre, kopier innhold tilbake til original a[] (nå b)
  79. System.arraycopy (a,0,b,0,a.length);
  80. }
  81. return a;
  82. } // end radixMulti
  83. class Worker extends Thread {
  84. int index;
  85. CyclicBarrier barrier;
  86. int[] a;
  87. int[] b;
  88. int[][] accumulated;
  89. int[] globalCount;
  90. int[][] count2d;
  91. int mask;
  92. int shift;
  93. int start;
  94. int end;
  95. boolean doD = false;
  96. int acumVal;
  97. int j;
  98. int[] count;
  99. Worker(
  100. int index, CyclicBarrier barrier,
  101. int[] a, int[] b, int[][] accumulated,
  102. int[] globalCount, int[][] count2d,
  103. int mask, int shift,
  104. int start, int end) {
  105. this.index = index;
  106. this.barrier = barrier;
  107. this.a = a;
  108. this.b = b;
  109. this.accumulated = accumulated;
  110. this.globalCount = globalCount;
  111. this.count2d = count2d;
  112. this.mask = mask;
  113. this.shift = shift;
  114. this.start = start;
  115. this.end = end;
  116. acumVal = 0;
  117. j = 0;
  118. count = new int[mask+1];
  119. }
  120. synchronized public void run() {
  121. // b) count=the frequency of each radix value in a
  122. for (int i = start; i < end; i++) {
  123. count[(a[i]>>> shift) & mask]++;
  124. }
  125. // c) Add up in 'count' - accumulated values
  126. for (int i = 0; i <= mask; i++) {
  127. count2d[index][i] = count[i];
  128. j = count[i];
  129. accumulated[index][i] = acumVal;
  130. acumVal += j;
  131. }
  132. // Wait for synchronization
  133. try { barrier.await(); } catch (Exception ex) {}
  134. while (!doD)
  135. try { wait(); } catch (InterruptedException ex) {}
  136. // d) move numbers in sorted order a to b
  137. int[] space = new int[mask + 1];
  138. for (int i = 0; i < mask + 1; ++i) {
  139. for (int j = 0; j < index; ++j) {
  140. space[i] += count2d[j][i];
  141. }
  142. }
  143. for (int i = start; i < end; i++) {
  144. int idx = (a[i] >>> shift) & mask;
  145. b[globalCount[idx] + space[idx]++] = a[i];
  146. }
  147. }
  148. synchronized public void startPartD() {
  149. this.doD = true;
  150. notify();
  151. }
  152. }
  153. /** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */
  154. void radixSort ( int [] a, int [] b, int maskLen, int shift){
  155. int mask = (1 << maskLen) - 1;
  156. CyclicBarrier barrier = new CyclicBarrier(nThreads + 1);
  157. int[][] accumulated = new int[nThreads][mask + 1];
  158. int[][] count2d = new int[nThreads][mask + 1];
  159. int[] count = new int[mask + 1];
  160. // Create and start workers
  161. Worker[] workers = new Worker[nThreads];
  162. int d = a.length / nThreads;
  163. for (int i = 0; i < nThreads; ++i) {
  164. int start = d * i;
  165. int end = i == nThreads - 1 ? a.length : d * (i + 1);
  166. workers[i] = new Worker(
  167. i, barrier,
  168. a, b, accumulated,
  169. count, count2d,
  170. mask, shift,
  171. start, end);
  172. workers[i].start();
  173. }
  174. // Synchronize
  175. try { barrier.await(); } catch (Exception ex) {}
  176. // Sequentially fix count
  177. for (int i=0; i < count.length; ++i) {
  178. for (int j = 0; j < nThreads; ++j) {
  179. count[i] += accumulated[j][i];
  180. }
  181. }
  182. // Do part D
  183. for (Worker w: workers) {
  184. w.startPartD();
  185. }
  186. // Join threads
  187. for (int i = 0; i < nThreads; ++i) {
  188. try { workers[i].join(); } catch (InterruptedException ex) {}
  189. }
  190. }// end radixSort
  191. void testSort(int [] a){
  192. for (int i = 0; i< a.length-1;i++) {
  193. if (a[i] > a[i+1]){
  194. System.out.println("SorteringsFEIL på plass: "+i +" a["+i+"]:"+a[i]+" > a["+(i+1)+"]:"+a[i+1]);
  195. return;
  196. }
  197. }
  198. }// end simple sorteingstest
  199. }// end SekvensiellRadix