RecursiveShuffle.tcc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #ifndef __RECURSIVESHUFFLE_TCC__
  2. #define __RECURSIVESHUFFLE_TCC__
  3. template<OSwap_Style oswap_style>
  4. void RecursiveShuffle_M2_inner(unsigned char *buf, uint64_t N, size_t block_size, bool *selected_list) {
  5. // Base cases
  6. FOAV_SAFE_CNTXT(RecursiveShuffle_M2_inner, N)
  7. if (N <= 1) {
  8. return;
  9. }
  10. FOAV_SAFE_CNTXT(RecursiveShuffle_M2_inner, N)
  11. if (N == 2) {
  12. //Flip a coin and swap the two
  13. unsigned char *packet_1 = buf;
  14. unsigned char *packet_2 = buf + block_size;
  15. bool swap_flag = getRandomBit();
  16. oswap_buffer<oswap_style>(packet_1, packet_2, block_size, swap_flag);
  17. return;
  18. }
  19. // MarkHalf the elements
  20. MarkHalf(N, selected_list);
  21. //TightCompact
  22. TightCompact<oswap_style>(buf, N, block_size, selected_list);
  23. // Recursively shuffle each half
  24. size_t lsize = N/2;
  25. size_t rsize = N - lsize;
  26. bool *selected_L = selected_list;
  27. bool *selected_R = selected_list + lsize;
  28. RecursiveShuffle_M2_inner<oswap_style>(buf, lsize, block_size, selected_L);
  29. RecursiveShuffle_M2_inner<oswap_style>(buf+ lsize*block_size, rsize, block_size, selected_R);
  30. }
  31. struct RecursiveShuffle_M2_inner_parallel_args {
  32. unsigned char *buf;
  33. uint64_t N;
  34. size_t block_size;
  35. bool *selected_list;
  36. size_t nthreads;
  37. };
  38. template<OSwap_Style oswap_style>
  39. void RecursiveShuffle_M2_inner_parallel(unsigned char *buf, uint64_t N, size_t block_size, bool *selected_list, size_t nthreads);
  40. template<OSwap_Style oswap_style>
  41. static void* RecursiveShuffle_M2_inner_parallel_launch(void *voidargs) {
  42. struct RecursiveShuffle_M2_inner_parallel_args *args =
  43. (RecursiveShuffle_M2_inner_parallel_args*)voidargs;
  44. RecursiveShuffle_M2_inner_parallel<oswap_style>(args->buf, args->N, args->block_size,
  45. args->selected_list, args->nthreads);
  46. return NULL;
  47. }
  48. template<OSwap_Style oswap_style>
  49. void RecursiveShuffle_M2_inner_parallel(unsigned char *buf, uint64_t N, size_t block_size, bool *selected_list, size_t nthreads) {
  50. FOAV_SAFE2_CNTXT(RS_M2_inner_parallel, nthreads, N)
  51. if (nthreads <= 1) {
  52. #ifdef VERBOSE_TIMINGS_RECSHUFFLE
  53. unsigned long start = printf_with_rtclock("Thread %u starting RecursiveShuffle_M2_inner(N=%lu)\n", g_thread_id, N);
  54. #endif
  55. RecursiveShuffle_M2_inner<oswap_style>(buf, N, block_size, selected_list);
  56. #ifdef VERBOSE_TIMINGS_RECSHUFFLE
  57. printf_with_rtclock_diff(start, "Thread %u ending RecursiveShuffle_M2_inner(N=%lu)\n", g_thread_id, N);
  58. #endif
  59. return;
  60. }
  61. // Base cases
  62. FOAV_SAFE_CNTXT(RecursiveShuffle_M2_inner, N)
  63. if (N <= 1) {
  64. return;
  65. }
  66. FOAV_SAFE_CNTXT(RecursiveShuffle_M2_inner, N)
  67. if (N == 2) {
  68. //Flip a coin and swap the two
  69. unsigned char *packet_1 = buf;
  70. unsigned char *packet_2 = buf + block_size;
  71. bool swap_flag = getRandomBit();
  72. oswap_buffer<oswap_style>(packet_1, packet_2, block_size, swap_flag);
  73. return;
  74. }
  75. #ifdef VERBOSE_TIMINGS_RECSHUFFLE
  76. unsigned long start = printf_with_rtclock("Thread %u starting RecursiveShuffle_M2_inner_parallel(N=%lu, nthreads=%lu)\n", g_thread_id, N, nthreads);
  77. #endif
  78. printf("Before MarkHalf\n");
  79. // MarkHalf the elements
  80. MarkHalf(N, selected_list);
  81. printf("After MarkHalf\n");
  82. //TightCompact
  83. TightCompact_parallel<oswap_style>(buf, N, block_size, selected_list, nthreads);
  84. // Recursively shuffle each half
  85. size_t lsize = N/2;
  86. size_t rsize = N - lsize;
  87. bool *selected_L = selected_list;
  88. bool *selected_R = selected_list + lsize;
  89. #if 1
  90. size_t lthreads = nthreads/2;
  91. size_t rthreads = nthreads - lthreads;
  92. /* The left half will be processed by thread g_thread_id + rthreads, which will
  93. * inherit threads g_thread_id+rthreads .. g_thread_id + nthreads-1. */
  94. threadid_t leftthreadid = g_thread_id + rthreads;
  95. RecursiveShuffle_M2_inner_parallel_args leftargs = {
  96. buf, lsize, block_size, selected_L, lthreads
  97. };
  98. threadpool_dispatch(leftthreadid,
  99. RecursiveShuffle_M2_inner_parallel_launch<oswap_style>,
  100. &leftargs);
  101. /* We will do the right half ourselves, on threads g_thread_id .. g_thread_id..rthreads-1 */
  102. RecursiveShuffle_M2_inner_parallel<oswap_style>(buf+ lsize*block_size, rsize, block_size, selected_R, rthreads);
  103. threadpool_join(leftthreadid, NULL);
  104. #else
  105. RecursiveShuffle_M2_inner_parallel<oswap_style>(buf, lsize, block_size, selected_L, nthreads);
  106. RecursiveShuffle_M2_inner_parallel<oswap_style>(buf+ lsize*block_size, rsize, block_size, selected_R, nthreads);
  107. #endif
  108. #ifdef VERBOSE_TIMINGS_RECSHUFFLE
  109. printf_with_rtclock_diff(start, "Thread %u ending RecursiveShuffle_M2_inner_parallel(N=%lu, nthreads=%lu)\n", g_thread_id, N, nthreads);
  110. #endif
  111. }
  112. #ifndef BEFTS_MODE
  113. template<OSwap_Style oswap_style>
  114. void RecursiveShuffle_M1_inner(unsigned char *buf, uint64_t N, size_t block_size, bool *selected_list) {
  115. FOAV_SAFE2_CNTXT(RS_M1_inner, N, block_size)
  116. // Base cases
  117. if (N == 1) {
  118. return;
  119. }
  120. FOAV_SAFE2_CNTXT(RS_M1_inner, N, block_size)
  121. if (N == 2) {
  122. //Flip a coin and swap the two
  123. unsigned char *packet_1 = buf;
  124. unsigned char *packet_2 = buf + block_size;
  125. bool swap_flag = getRandomBit();
  126. oswap_buffer<oswap_style>(packet_1, packet_2, block_size, swap_flag);
  127. return;
  128. }
  129. // MarkHalf the elements
  130. MarkHalf(N, selected_list);
  131. //TightCompact
  132. OP_TightCompact<oswap_style>(buf, N, block_size, selected_list);
  133. // Recursively shuffle each half
  134. size_t l_size = N/2;
  135. size_t r_size = N-l_size;
  136. bool *selected_L = selected_list;
  137. bool *selected_R = selected_list + l_size;
  138. RecursiveShuffle_M1_inner<oswap_style>(buf, l_size, block_size, selected_L);
  139. RecursiveShuffle_M1_inner<oswap_style>(buf+(l_size*block_size), r_size, block_size, selected_R);
  140. }
  141. #endif
  142. #endif