chunkedseq
container library for large in-memory data sets
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bench.cpp
Go to the documentation of this file.
1 
14 #include <functional>
15 #include <random>
16 #include <algorithm>
17 #include <assert.h>
18 #include <unordered_map>
19 
20 #include "cmdline.hpp"
21 #include "atomic.hpp"
22 #include "microtime.hpp"
23 
24 // "ls_bag.hpp"
25 #include "container.hpp"
26 #include "fixedcapacity.hpp"
27 #include "chunkedseq.hpp"
28 #include "chunkedbag.hpp"
29 #include "map.hpp"
30 
31 #ifdef USE_MALLOC_COUNT
32 #include "malloc_count.h"
33 #endif
34 
35 using namespace pasl;
36 using namespace pasl::util;
38 
39 /***********************************************************************/
40 
41 typedef size_t result_t;
42 
43 typedef std::function<void ()> thunk_t;
44 
46 void failwith(std::string s) {
47  std::cout << s << std::endl;
48  exit(1);
49 }
50 
52 double exec_time;
53 
54 /*---------------------------------------------------------------------*/
55 
56 /*
57  * Pseudo-random generator defined by the congruence S' = 69070 * S
58  * mod (2^32 - 5). Marsaglia (CACM July 1993) says on page 107 that
59  * this is a ``good one''. There you go.
60  *
61  * The literature makes a big fuss about avoiding the division, but
62  * for us it is not worth the hassle.
63  */
64 static const unsigned RNGMOD = ((1ULL << 32) - 5);
65 static const unsigned RNGMUL = 69070U;
66 unsigned rand_seed;
67 
68 unsigned myrand() {
69  unsigned state = rand_seed;
70  state = (unsigned)((RNGMUL * (unsigned long long)state) % RNGMOD);
71  rand_seed = state;
72  return state;
73 }
74 
75 void mysrand(unsigned seed) {
76  seed %= RNGMOD;
77  seed += (seed == 0); /* 0 does not belong to the multiplicative
78  group. Use 1 instead */
79  rand_seed = seed;
80 }
81 
82 /*---------------------------------------------------------------------*/
83 
84 class bytes_1 {
85 public:
86  char data;
87  bytes_1() { }
88  bytes_1(char c) : data(c) { }
89  bytes_1(size_t i) {
90  data = (char) (i % 256);
91  }
92  size_t get() const {
93  return (size_t) data;
94  }
95  char get_char() const {
96  return data;
97  }
98  bool operator==(const bytes_1 other) {
99  return data == other.data;
100  }
101  operator unsigned char() const {
102  return data;
103  }
104 };
105 
106 class bytes_8 {
107 public:
108  uint64_t data;
109  bytes_8() { }
110  bytes_8(char c) {
111  data = (uint64_t)c;
112  }
113  bytes_8(size_t i) {
114  data = i;
115  }
116  size_t get() const {
117  return data;
118  }
119  char get_char() const {
120  return (char) (data % 256);
121  }
122  bool operator==(const bytes_8 other) {
123  return data == other.data;
124  }
125 };
126 
127 class bytes_64 {
128 public:
129  int64_t data[8];
130  bytes_64() { }
131  bytes_64(char c) {
132  for (int k = 0; k < 8; k++)
133  data[k] = (int64_t)c;
134  }
135  bytes_64(size_t i) {
136  for (int k = 0; k < 8; k++)
137  data[k] = i;
138  }
139  size_t get() const {
140  return data[0];
141  }
142  char get_char() const {
143  return (char) (data[0] % 256);
144  }
145  bool operator==(const bytes_64 other) {
146  return data == other.data;
147  }
148 };
149 
150 /* reorders in a random fashion the items of the given container
151  */
152 template <class Datastruct>
153 void shuffle(Datastruct& d) {
154  size_t sz = d.size();
155  for (size_t i = 0; i < sz; i++)
156  std::swap(d[i], d[rand() % sz]);
157 }
158 
159 /*---------------------------------------------------------------------*/
160 /* Scenarios */
161 
162 
163 template <class Datastruct>
165  typedef typename Datastruct::value_type value_type;
166  size_t nb_total = (size_t) cmdline::parse_or_default_int64("n", 100000000);
167  size_t repeat = (size_t) cmdline::parse_or_default_int64("r", 1000);
168  size_t block = nb_total / repeat;
169  return [=] {
170  printf("length %lld\n",block);
171  uint64_t start_time = microtime::now();
172  Datastruct d;
173  Datastruct r;
174  res = 0;
175  for (size_t j = 0; j < repeat; j++) {
176  for (size_t i = 0; i < block; i++) {
177  d.push_back(value_type(i));
178  res += i;
179  }
180  for (size_t i = 0; i < block; i++) {
181  res += d.pop_front().get();
182  d.push_back(value_type(i));
183  size_t v = d.pop_front().get();
184  r.push_back(value_type(v));
185  }
186  }
187  exec_time = microtime::seconds_since(start_time);
188  };
189 }
190 
191 
192 // #define FIFO_LIFO_ONLY_COUNT_POP 1
193 
194 /* Common code for various lifo versions */
196 template <class Datastruct, bool SkipPop>
198  typedef typename Datastruct::value_type value_type;
199  size_t nb_total = (size_t) cmdline::parse_or_default_int64("n", 100000000);
200  size_t repeat = (size_t) cmdline::parse_or_default_int64("r", 1000);
201  size_t block = nb_total / repeat;
202  return [=] {
203  printf("length %lld\n",block);
204  uint64_t start_time = microtime::now();
205  Datastruct d;
206  res = 0;
207  for (size_t j = 0; j < repeat; j++) {
208  for (size_t i = 0; i < block; i++) {
209  d.push_back(value_type(i));
210  res += i;
211  }
212  #ifdef FIFO_LIFO_ONLY_COUNT_POP
213  start_time = microtime::now();
214  #endif
215  if (!SkipPop) {
216  for (size_t i = 0; i < block; i++) {
217  res += d.pop_back().get();
218  }
219  }
220  }
221  // if (SkipPop)
222  // res += d.size();
223  exec_time = microtime::seconds_since(start_time);
224  };
225 }
226 
227 template <class Datastruct>
229  return scenario_lifo_with_or_without_pop<Datastruct, false>();
230 }
231 
232 template <class Datastruct>
234  return scenario_lifo_with_or_without_pop<Datastruct, true>();
235 }
236 
237 template <class Datastruct>
239  typedef typename Datastruct::value_type value_type;
240  size_t nb_total = (size_t) cmdline::parse_or_default_int64("n", 100000000);
241  size_t repeat = (size_t) cmdline::parse_or_default_int64("r", 1000);
242  size_t block = nb_total / repeat;
243  return [=] {
244  printf("length %lld\n",block);
245  uint64_t start_time = microtime::now();
246  Datastruct d;
247  res = 0;
248  for (size_t j = 0; j < repeat; j++) {
249  for (size_t i = 0; i < block; i++) {
250  d.push_back(value_type(i));
251  res += i;
252  }
253  #ifdef FIFO_LIFO_ONLY_COUNT_POP
254  start_time = microtime::now();
255  #endif
256  for (size_t i = 0; i < block; i++) {
257  res += d.pop_front().get();
258  }
259  }
260  exec_time = microtime::seconds_since(start_time);
261  };
262 }
263 
264 
265 // p should be 2 or more
266 template <class Datastruct, bool should_push, bool should_pop>
267 void _scenario_split_merge(Datastruct* ds, size_t n, size_t p, size_t r, size_t h) {
268  typedef typename Datastruct::value_type value_type;
269  typedef typename Datastruct::size_type size_type;
270 
271  size_t nb_total = n / p;
272  printf("length %lld\n",nb_total);
273 
274  srand(14);
275  for (size_type i = 0; i < p; i++) {
276  for (size_type j = 0; j < nb_total; j++)
277  ds[i].push_back(value_type((char)1));
278  }
279  uint64_t start_time = microtime::now();
280  for (size_type k = 0; k < r; k++) {
281  size_type b1 = rand() % p;
282  size_type b2 = rand() % (p-1);
283  if (b2 >= b1)
284  b2++;
285  // b1 != b2
286  ds[b1].concat(ds[b2]);
287  // ds[b2].empty() == true
288  size_type b3 = rand() % (p-1);
289  if (b3 >= b2)
290  b3++;
291  // b3 != b2
292  Datastruct& src = ds[b3];
293  if (src.size() > 1) {
294  size_t posn = src.size() / 2;
295  src.split(posn, ds[b2]);
296  }
297  if (should_push)
298  for (size_t i = 0; i < h; i++)
299  src.push_back(value_type(i));
300  if (should_pop)
301  for (size_t i = 0; i < h; i++)
302  res += (size_type)src.pop_front().get();
303  }
304  exec_time = microtime::seconds_since(start_time);
305  res = 0;
306  for (int i = 0; i < p; i++)
307  res += ds[i].size();
308 }
309 
310 template <class Datastruct>
312  typedef typename Datastruct::value_type value_type;
313  typedef typename Datastruct::size_type size_type;
314  size_t n = (size_t) cmdline::parse_or_default_int64("n", 100000000);
315  size_t p = (size_t) cmdline::parse_or_default_int64("p", std::max(n/100, (size_type)2));
316  size_t r = (size_t) cmdline::parse_or_default_int64("r", 100000);
317  size_t h = (size_t) cmdline::parse_or_default_int64("h", 0);
318  bool should_push = cmdline::parse_or_default_bool("should_push", true);
319  bool should_pop = cmdline::parse_or_default_bool("should_pop", false);
320 
321  return [=] {
322  Datastruct* ds = new Datastruct[p];
323  if (should_push && should_pop)
324  _scenario_split_merge<Datastruct,true,true>(ds, n, p, r, h);
325  else if (! should_push && should_pop)
326  _scenario_split_merge<Datastruct,false,true>(ds, n, p, r, h);
327  else if (should_push && ! should_pop)
328  _scenario_split_merge<Datastruct,true,false>(ds, n, p, r, h);
329  else
330  _scenario_split_merge<Datastruct,false,false>(ds, n, p, r, h);
331  delete [] ds;
332  };
333 }
334 
335 template <class Datastruct, class Filter>
336 void filter(Datastruct& dst, Datastruct& src, const Filter& filt, int cutoff) {
337  typedef typename Datastruct::value_type value_type;
338  if (src.size() <= cutoff) {
339  while (! src.empty()) {
340  value_type item = src.pop_back();
341  if (filt(item))
342  dst.push_back(item);
343  }
344  } else {
345  Datastruct src2;
346  Datastruct dst2;
347  size_t mid = src.size() / 2;
348  src.split(mid, src2);
349  filter(dst, src, filt, cutoff);
350  filter(dst2, src2, filt, cutoff);
351  dst.concat(dst2);
352  }
353 }
354 
355 template <class Datastruct>
357  typedef typename Datastruct::size_type size_type;
358  typedef typename Datastruct::value_type value_type;
359  size_t cutoff = cmdline::parse_or_default_int64("cutoff", 8096);
360  size_t n = cmdline::parse_or_default_int64("n", 100000000);
361  size_t r = (size_t) cmdline::parse_or_default_int64("r", 1);
362  size_t nb_total = n / r;
363  printf("length %lld\n",nb_total);
364  const size_t m = 1<<30;
365  return [=] {
366  Datastruct src;
367  Datastruct dst;
368  for (size_t i = 0; i < nb_total; i++)
369  src.push_back(value_type(i));
370  auto filt = [] (value_type v) {
371  return (v.get() % m) != 0;
372  };
373  uint64_t start_time = microtime::now();
374  for (size_t i = 0; i < r; i++) {
375  filter(dst, src, filt, cutoff);
376  dst.swap(src);
377  }
378  exec_time = microtime::seconds_since(start_time);
379  res = src.size() + dst.size();
380  //assert(dst.size() == n - ((n+m-1)/m));
381  };
382 }
383 
384 #ifndef SKIP_MAP
385 
386 /* All of these dictionary benchmarks are taken from:
387  * http://tommyds.sourceforge.net/doc/benchmark.html
388  */
389 #define PAYLOAD 16 // Size of the object
390 
391 template <class Map,class Obj>
393  using map_type = Map;
394  using key_type = typename map_type::key_type;
395  using obj_type = Obj;
396  using mapped_type = typename map_type::mapped_type;
397 
398  size_t n = cmdline::parse_or_default_uint64("n", 1000000);
399  bool test_random = cmdline::parse_or_default_bool("test_random", true);
400  key_type* INSERT = new key_type[n];
401  key_type* SEARCH = new key_type[n];
402  obj_type* OBJ = new obj_type[n];
403 
404  // Initialize the keys
405  for(long i=0;i<n;++i) {
406  INSERT[i] = 0x80000000 + i * 2;
407  SEARCH[i] = 0x80000000 + i * 2;
408  }
409 
410  // If random order is required, shuffle the keys with Fisher-Yates
411  // The two key orders are not correlated
412  if (test_random) {
413  std::random_shuffle(INSERT, INSERT + n);
414  std::random_shuffle(SEARCH, SEARCH + n);
415  }
416 
417  auto init = [=] (map_type& bag) {
418  for(size_t i=0;i<n;++i) {
419  // Setup the element to insert
420  key_type key = INSERT[i];
421  auto element = &OBJ[i];
422  element->value = key;
423 
424  // Insert it
425  bag[key] = element;
426  }
427  };
428 
429  cmdline::argmap_dispatch c;
430  c.add("insert", [=] {
431  map_type bag;
432  uint64_t start_time = microtime::now();
433  init(bag);
434  exec_time = microtime::seconds_since(start_time);
435  res = bag.size();
436  });
437  c.add("change", [=] {
438  map_type bag;
439  init(bag);
440  uint64_t start_time = microtime::now();
441 
442  for(size_t i=0;i<n;++i) {
443  // Search the element
444  unsigned key = SEARCH[i];
445  auto j = bag.find(key);
446  if (j == bag.end())
447  abort();
448 
449  // Remove it
450  auto element = (*j).second;
451  bag.erase(j);
452 
453  // Reinsert the element with a new key
454  // Use +1 in the key to ensure that the new key is unique
455  key = INSERT[i] + 1;
456  element->value = key;
457  bag[key] = element;
458  }
459  exec_time = microtime::seconds_since(start_time);
460  res = bag.size();
461  });
462  c.add("hit", [=] {
463  map_type bag;
464  init(bag);
465  uint64_t start_time = microtime::now();
466  for(size_t i=0;i<n;++i) {
467  // Search the element
468  // Use a different key order than insertion
469  auto key = SEARCH[i];
470  auto j = bag.find(key);
471  if (j == bag.end())
472  abort();
473 
474  // Ensure that it's the correct element.
475  // This operation is like using the object after finding it,
476  // and likely involves a cache-miss operation.
477  auto element = (*j).second;
478  if (element->value != key)
479  abort();
480  }
481  exec_time = microtime::seconds_since(start_time);
482  res = bag.size();
483  });
484  c.add("miss", [=] {
485  map_type bag;
486  init(bag);
487  uint64_t start_time = microtime::now();
488  for(size_t i=0;i<n;++i) {
489  // Search the element
490  key_type key = SEARCH[i]+1;
491  auto j = bag.find(key);
492  /* if (j != bag.end())
493  abort(); */
494  }
495  exec_time = microtime::seconds_since(start_time);
496  res = bag.size();
497  });
498  c.add("remove", [=] {
499  map_type bag;
500  init(bag);
501  uint64_t start_time = microtime::now();
502  for(size_t i=0;i<n;++i) {
503  // Search the element
504  auto key = SEARCH[i];
505  auto j = bag.find(key);
506  if (j == bag.end())
507  abort();
508 
509  // Remove it
510  bag.erase(j);
511 
512  // Ensure that it's the correct element.
513  auto element = (*j).second;
514  /* if (element->value != key)
515  abort(); */
516  }
517  exec_time = microtime::seconds_since(start_time);
518  res = bag.size();
519  });
520 
521  return c.find_by_arg("map_benchmark");
522 }
523 #endif
524 
525 /*---------------------------------------------------------------------*/
526 // dispatch tests
527 
528 template <class Sequence>
530  cmdline::argmap_dispatch c;
531  c.add("test", scenario_test<Sequence>());
532  c.add("fifo", scenario_fifo<Sequence>());
533  c.add("lifo", scenario_lifo<Sequence>());
534  c.add("fill_back", scenario_fill_back<Sequence>());
535  c.add("split_merge", scenario_split_merge<Sequence>());
536  c.add("filter", scenario_filter<Sequence>());
537  cmdline::dispatch_by_argmap(c, "scenario");
538 }
539 
540 /*---------------------------------------------------------------------*/
541 // dispatch sequences
542 
543 #include "cachedmeasure.hpp"
544 #include "fixedcapacity.hpp"
545 template <
546  template <
547  class Item,
548  int Chunk_capacity=512,
550 template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct = pasl::data::fixedcapacity::heap_allocated::ringbuffer_ptr,
551  class Item_alloc=std::allocator<Item> > class SeqStruct,
552  class Item,
553  template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct>
556  static constexpr int default_chunksize = 512;
557  util::cmdline::argmap_dispatch c;
558  c.add("512", [] { dispatch_by_scenario<SeqStruct<Item,512,Cache,Chunk_struct> >(); });
559  #ifndef SKIP_CHUNKSIZE
560  c.add("64", [] { dispatch_by_scenario<SeqStruct<Item,64,Cache,Chunk_struct> >(); });
561  c.add("128", [] { dispatch_by_scenario<SeqStruct<Item,128,Cache,Chunk_struct> >(); });
562  c.add("256", [] { dispatch_by_scenario<SeqStruct<Item,256,Cache,Chunk_struct> >(); });
563  c.add("1024", [] { dispatch_by_scenario<SeqStruct<Item,1024,Cache,Chunk_struct> >(); });
564  c.add("2048", [] { dispatch_by_scenario<SeqStruct<Item,2048,Cache,Chunk_struct> >(); });
565  c.add("4096", [] { dispatch_by_scenario<SeqStruct<Item,4096,Cache,Chunk_struct> >(); });
566  c.add("8192", [] { dispatch_by_scenario<SeqStruct<Item,8192,Cache,Chunk_struct> >(); });
567  #endif
568  util::cmdline::dispatch_by_argmap(c, "chunk_size", std::to_string(default_chunksize));
569 }
570 
571 
572 template <class Item,
573 int Chunk_capacity=512,
575 template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct=data::fixedcapacity::heap_allocated::ringbuffer_ptr,
576 class Item_alloc=std::allocator<Item> >
577 using mystack = chunkedseq::bootstrapped::stack<Item, Chunk_capacity, Cache>;
578 
579 template <class Item,
580 int Chunk_capacity=512,
582 template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct=data::fixedcapacity::heap_allocated::ringbuffer_ptr,
583 class Item_alloc=std::allocator<Item> >
584 using mybag = chunkedseq::bootstrapped::bagopt<Item, Chunk_capacity, Cache>;
585 
586 
587 template <class Item,
588 int Chunk_capacity=512,
590 template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct=data::fixedcapacity::heap_allocated::ringbuffer_ptr,
591 class Item_alloc=std::allocator<Item> >
592 using myfftreestack = chunkedseq::ftree::stack<Item, Chunk_capacity, Cache>;
593 
594 template <class Item,
595 int Chunk_capacity=512,
597 template<class Chunk_item, int Cap, class Item_alloc2=std::allocator<Item>> class Chunk_struct=data::fixedcapacity::heap_allocated::ringbuffer_ptr,
598 class Item_alloc=std::allocator<Item> >
599 using myfftreebag = chunkedseq::ftree::bagopt<Item, Chunk_capacity, Cache>;
600 
601 template <class Item>
603  util::cmdline::argmap_dispatch c;
604  #ifndef SKIP_DEQUE
605  c.add("stl_deque", [] {
606  using seq_type = pasl::data::stl::deque_seq<Item>;
607  dispatch_by_scenario<seq_type>();
608  });
609  #endif
610  #ifndef SKIP_ROPE
611  #ifdef HAVE_ROPE
612  c.add("stl_rope", [] {
613  using seq_type = pasl::data::stl::rope_seq<Item>;
614  dispatch_by_scenario<seq_type>();
615  });
616  #endif
617  #endif
618  #ifndef SKIP_CHUNKEDSEQ
619  c.add("chunkedseq", [] {
620  dispatch_for_chunkedseq<chunkedseq::bootstrapped::deque, Item, data::fixedcapacity::heap_allocated::ringbuffer_ptr>();
621  });
622  #endif
623  #ifndef SKIP_CHUNKEDSEQ_OPT
624  c.add("chunkedseq_stack", [] {
625  dispatch_for_chunkedseq<mystack, Item, data::fixedcapacity::heap_allocated::stack>();
626  });
627  c.add("chunkedseq_bag", [] {
628  dispatch_for_chunkedseq<mybag, Item, data::fixedcapacity::heap_allocated::stack>();
629  });
630  #endif
631 
632 #ifndef SKIP_FTREE
633  c.add("chunkedftree", [] {
634  dispatch_for_chunkedseq<chunkedseq::ftree::deque, Item, data::fixedcapacity::heap_allocated::ringbuffer_ptr>();
635  });
636 #endif
637 #ifndef SKIP_FTREE_OPT
638  c.add("chunkedftree_stack", [] {
639  dispatch_for_chunkedseq<myfftreestack, Item, data::fixedcapacity::heap_allocated::stack>();
640  });
641  c.add("chunkedftree_bag", [] {
642  dispatch_for_chunkedseq<myfftreebag, Item, data::fixedcapacity::heap_allocated::stack>();
643  });
644 #endif
645  util::cmdline::dispatch_by_argmap(c, "sequence");
646 }
647 
648 /*---------------------------------------------------------------------*/
649 // dispatch itemsize
650 
652  static constexpr int default_itemsize = 8;
653  util::cmdline::argmap_dispatch c;
654  c.add("8", [] { dispatch_by_sequence<bytes_8>(); });
655  #ifndef SKIP_ITEMSIZE
656  c.add("1", [] { dispatch_by_sequence<bytes_1>(); });
657  c.add("64", [] { dispatch_by_sequence<bytes_64>(); });
658  #endif
659  util::cmdline::dispatch_by_argmap(c, "itemsize", std::to_string(default_itemsize));
660 }
661 
662 /*---------------------------------------------------------------------*/
663 // dispatch maps
664 
665 #ifndef SKIP_MAP
667  cmdline::argmap_dispatch c;
668  using key_type = long;
669  using obj_type = struct {
670  key_type value;
671  char payload[PAYLOAD];
672  };
673  using value_type = obj_type*;
674  using stl_map_type = std::map<key_type, value_type>;
675  using chunkedseq_map_type = data::map::map<key_type, value_type>;
676  using unordered_map_type = std::unordered_map<key_type, value_type>;
677  c.add("stl_map", scenario_map<stl_map_type,obj_type>());
678  c.add("chunkedseq_map", scenario_map<chunkedseq_map_type,obj_type>());
679  c.add("stl_unordered_set", scenario_map<unordered_map_type,obj_type>());
680  cmdline::dispatch_by_argmap(c, "map");
681 }
682 #else
683 void dispatch_by_map() {
684  abort();
685 }
686 #endif
687 
688 
689 /*---------------------------------------------------------------------*/
690 
692  cmdline::argmap_dispatch c;
693  c.add("sequence", [] { dispatch_by_itemsize(); });
694  c.add("map", [] { dispatch_by_map(); });
695  cmdline::dispatch_by_argmap(c, "mode", "sequence");
696 }
697 
698 int main(int argc, char** argv) {
699  pasl::util::cmdline::set(argc, argv);
700  mysrand(233432432);
701  res = 0;
702 
704 
705  printf ("exectime %lf\n", exec_time);
706  printf("result %lld\n", (long long)res);
707 
708  #ifdef USE_MALLOC_COUNT
709  malloc_pasl_report();
710  #endif
711  return 0;
712 }
713 
714 
715 
716 
717 /***********************************************************************/
thunk_t scenario_filter()
Definition: bench.cpp:356
thunk_t scenario_lifo()
Definition: bench.cpp:228
base::ringbuffer_ptr< base::heap_allocator< Item, Capacity+1 >> ringbuffer_ptr
unsigned rand_seed
Definition: bench.cpp:66
Chunked-bag functor.
STL-style map data structure.
thunk_t scenario_map()
Definition: bench.cpp:392
unsigned myrand()
Definition: bench.cpp:68
void dispatch_by_sequence()
Definition: bench.cpp:602
thunk_t scenario_fifo()
Definition: bench.cpp:238
void dispatch_by_benchmark_mode()
Definition: bench.cpp:691
#define PAYLOAD
Definition: bench.cpp:389
Definition: algebra.hpp:18
Fixed capacity vectors.
thunk_t scenario_test()
Definition: bench.cpp:164
chunkedseq::bootstrapped::bagopt< Item, Chunk_capacity, Cache > mybag
Definition: bench.cpp:584
Definitions of a few cached-measurement policies.
void dispatch_by_map()
Definition: bench.cpp:666
chunkedseq::ftree::bagopt< Item, Chunk_capacity, Cache > myfftreebag
Definition: bench.cpp:599
result_t res
Definition: bench.cpp:51
chunkedseq::bootstrapped::stack< Item, Chunk_capacity, Cache > mystack
Definition: bench.cpp:577
void failwith(std::string s)
Definition: bench.cpp:46
void shuffle(Datastruct &d)
Definition: bench.cpp:153
thunk_t scenario_split_merge()
Definition: bench.cpp:311
void dispatch_by_scenario()
Definition: bench.cpp:529
double exec_time
Definition: bench.cpp:52
void dispatch_by_itemsize()
Definition: bench.cpp:651
thunk_t scenario_lifo_with_or_without_pop()
Definition: bench.cpp:197
void _scenario_split_merge(Datastruct *ds, size_t n, size_t p, size_t r, size_t h)
Definition: bench.cpp:267
void dispatch_for_chunkedseq()
Definition: bench.cpp:554
std::function< void()> thunk_t
Definition: bench.cpp:43
thunk_t scenario_fill_back()
Definition: bench.cpp:233
int main(int argc, char **argv)
Definition: bench.cpp:698
size_t result_t
Definition: bench.cpp:41
bytes_8 Item
Definition: do_fifo.cpp:107
void filter(Datastruct &dst, Datastruct &src, const Filter &filt, int cutoff)
Definition: bench.cpp:336
void mysrand(unsigned seed)
Definition: bench.cpp:75
chunkedseq::ftree::stack< Item, Chunk_capacity, Cache > myfftreestack
Definition: bench.cpp:592
Chunked-sequence functor.