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.

284 lines
8.2 KiB

  1. #include <memory>
  2. #include <cassert>
  3. #include <cstdio>
  4. #include <stdlib.h>
  5. #include <algorithm>
  6. #include <vector>
  7. // enable debugging code in spp_bitset.h
  8. #define SPP_TEST 1
  9. #include <sparsepp/spp_timer.h>
  10. #include <sparsepp/spp_memory.h>
  11. #include <sparsepp/spp_bitset.h>
  12. using namespace std;
  13. // -----------------------------------------------------------
  14. // -----------------------------------------------------------
  15. template <size_t N>
  16. class TestBitset
  17. {
  18. public:
  19. typedef spp::spp_bitset<N> BS;
  20. TestBitset()
  21. {}
  22. void test_set(size_t num_iter)
  23. {
  24. size_t num_errors = 0;
  25. BS bs, bs2;
  26. printf("testing set on spp_bitset<%zu> , num_iter=%6zu -> ", N, num_iter);
  27. for (size_t i=0; i<num_iter; ++i)
  28. {
  29. bs.reset();
  30. bs2.reset();
  31. size_t start = rand() % N;
  32. size_t to = start + rand() % (N - start);
  33. bs.set(start, to);
  34. bs2.set_naive(start, to);
  35. bool same = bs == bs2;
  36. if (!same)
  37. ++num_errors;
  38. assert(same);
  39. }
  40. printf("num_errors = %zu\n", num_errors);
  41. }
  42. void test_reset(size_t num_iter)
  43. {
  44. size_t num_errors = 0;
  45. BS bs, bs2;
  46. printf("testing reset on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
  47. for (size_t i=0; i<num_iter; ++i)
  48. {
  49. bs.set();
  50. bs2.set();
  51. size_t start = rand() % N;
  52. size_t to = start + rand() % (N - start);
  53. bs.reset(start, to);
  54. bs2.reset_naive(start, to);
  55. bool same = bs == bs2;
  56. if (!same)
  57. ++num_errors;
  58. assert(same);
  59. }
  60. printf("num_errors = %zu\n", num_errors);
  61. }
  62. void test_all(size_t num_iter)
  63. {
  64. size_t num_errors = 0;
  65. BS bs;
  66. printf("testing all() on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
  67. for (size_t i=0; i<4 * N; ++i)
  68. {
  69. bs.set(rand() % N);
  70. if (i > 2 * N)
  71. {
  72. for (size_t j=0; j<num_iter; ++j)
  73. {
  74. size_t start = rand() % N;
  75. size_t to = start + rand() % (N - start);
  76. bool same = bs.all(start, to) == bs.all_naive(start, to);
  77. if (!same)
  78. ++num_errors;
  79. assert(same);
  80. }
  81. size_t start = 0, start_naive = 1;
  82. bs.all(start);
  83. bs.all_naive(start_naive);
  84. bool same = (start == start_naive);
  85. if (!same)
  86. ++num_errors;
  87. assert(same);
  88. }
  89. }
  90. printf("num_errors = %zu\n", num_errors);
  91. }
  92. void test_any(size_t num_iter)
  93. {
  94. size_t num_errors = 0;
  95. BS bs;
  96. printf("testing any() on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
  97. for (size_t i=0; i<num_iter; ++i)
  98. {
  99. bs.set(rand() % N);
  100. for (size_t j=0; j<100; ++j)
  101. {
  102. size_t start = rand() % N;
  103. size_t to = start + rand() % (N - start);
  104. bool same = bs.any(start, to) == bs.any_naive(start, to);
  105. if (!same)
  106. ++num_errors;
  107. assert(same);
  108. }
  109. }
  110. printf("num_errors = %zu\n", num_errors);
  111. }
  112. void test_longest(size_t num_iter)
  113. {
  114. size_t num_errors = 0;
  115. BS bs, bs2;
  116. assert(bs.longest_zero_sequence() == N);
  117. bs.set(0);
  118. assert(bs.longest_zero_sequence() == N-1);
  119. bs.set(10);
  120. assert(bs.find_next_n(3, 8) == 11);
  121. assert(bs.find_next_n(3, 6) == 6);
  122. assert(bs.find_next_n(3, N-2) == 1);
  123. assert(bs.longest_zero_sequence() == N-11);
  124. if (N > 1000)
  125. {
  126. bs.set(1000);
  127. size_t longest = bs.longest_zero_sequence();
  128. assert(longest == 1000-11 || longest == N-1001);
  129. if (!(longest == 1000-11 || longest == N-1001))
  130. ++num_errors;
  131. }
  132. spp::Timer<std::milli> timer_lz;
  133. spp::Timer<std::milli> timer_lz_slow;
  134. float lz_time(0), lz_time_slow(0);
  135. printf("testing longest_zero_sequence() , num_iter=%6zu -> ", num_iter);
  136. srand(1);
  137. for (size_t i=0; i<num_iter; ++i)
  138. {
  139. bs.reset();
  140. for (size_t j=0; j<N; ++j)
  141. {
  142. bs.set(rand() % N);
  143. timer_lz.snap();
  144. size_t lz1 = bs.longest_zero_sequence();
  145. lz_time += timer_lz.get_delta();
  146. timer_lz_slow.snap();
  147. size_t lz2 = bs.longest_zero_sequence_naive();
  148. lz_time_slow += timer_lz_slow.get_delta();
  149. num_errors += (lz1 != lz2);
  150. assert(!num_errors);
  151. }
  152. }
  153. printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, lz_time, lz_time_slow);
  154. }
  155. void test_longest2(size_t num_iter)
  156. {
  157. size_t num_errors = 0;
  158. BS bs, bs2;
  159. assert(bs.longest_zero_sequence() == N);
  160. bs.set(0);
  161. assert(bs.longest_zero_sequence() == N-1);
  162. bs.set(10);
  163. assert(bs.find_next_n(3, 8) == 11);
  164. assert(bs.find_next_n(3, 6) == 6);
  165. assert(bs.find_next_n(3, N-2) == 1);
  166. assert(bs.longest_zero_sequence() == N-11);
  167. if (N > 1000)
  168. {
  169. bs.set(1000);
  170. size_t longest = bs.longest_zero_sequence();
  171. assert(longest == 1000-11 || longest == N-1001);
  172. if (!(longest == 1000-11 || longest == N-1001))
  173. ++num_errors;
  174. }
  175. spp::Timer<std::milli> timer_lz;
  176. spp::Timer<std::milli> timer_lz_slow;
  177. float lz_time(0), lz_time_slow(0);
  178. printf("testing longest_zero_sequence2() , num_iter=%6zu -> ", num_iter);
  179. srand(1);
  180. for (size_t i=0; i<num_iter; ++i)
  181. {
  182. bs.reset();
  183. for (size_t j=0; j<N; ++j)
  184. {
  185. bs.set(rand() % N);
  186. size_t start_pos1 = 0, start_pos2 = 0;
  187. timer_lz.snap();
  188. size_t lz1 = bs.longest_zero_sequence(64, start_pos1);
  189. lz_time += timer_lz.get_delta();
  190. timer_lz_slow.snap();
  191. size_t lz2 = bs.longest_zero_sequence_naive(64, start_pos2);
  192. lz_time_slow += timer_lz_slow.get_delta();
  193. assert(start_pos1 == start_pos2);
  194. num_errors += (lz1 != lz2) || (start_pos1 != start_pos2);
  195. assert(!num_errors);
  196. }
  197. }
  198. printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, lz_time, lz_time_slow);
  199. }
  200. void test_ctz(size_t num_iter)
  201. {
  202. size_t num_errors = 0;
  203. spp::Timer<std::milli> timer_ctz;
  204. spp::Timer<std::milli> timer_ctz_slow;
  205. float ctz_time(0), ctz_time_slow(0);
  206. printf("testing count_trailing_zeroes() , num_iter=%6zu -> ", num_iter);
  207. for (size_t i=0; i<num_iter; ++i)
  208. {
  209. size_t v = rand() ^ (rand() << 16);
  210. timer_ctz.snap();
  211. uint32_t ctz1 = spp::count_trailing_zeroes(v);
  212. ctz_time += timer_ctz.get_delta();
  213. timer_ctz_slow.snap();
  214. size_t ctz2 = spp::count_trailing_zeroes_naive(v);
  215. ctz_time_slow += timer_ctz_slow.get_delta();
  216. num_errors += (ctz1 != ctz2);
  217. assert(!num_errors);
  218. }
  219. printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, ctz_time, ctz_time_slow);
  220. }
  221. void run()
  222. {
  223. test_ctz(10000);
  224. test_all(10000);
  225. test_any(1000);
  226. test_set(1000);
  227. test_reset(1000);
  228. test_longest(200);
  229. test_longest2(200);
  230. }
  231. };
  232. // -----------------------------------------------------------
  233. // -----------------------------------------------------------
  234. int main()
  235. {
  236. TestBitset<1024> test_bitset_1024;
  237. test_bitset_1024.run();
  238. TestBitset<4096> test_bitset_4096;
  239. test_bitset_4096.run();
  240. //TestBitset<8192> test_bitset_8192;
  241. //test_bitset_8192.run();
  242. }