// File: lemire[P]fastscancount/benchmark/counters.cpp
// Function: demo_random(unsigned long, unsigned long, unsigned long, unsigned long)
void demo_random(size_t N, size_t length, size_t array_count, size_t threshold) {
  std::vector<std::vector<uint32_t>> data(array_count);

  std::vector<const std::vector<uint32_t>*> data_ptrs;
  std::vector<uint32_t> answer;
  answer.reserve(N);

  size_t sum = 0;
  for (size_t c = 0; c < array_count; c++) {
    std::vector<uint32_t> &v = data[c];
    for (size_t i = 0; i < length; i++) {
      v.push_back(rand() % N);
    }
    std::sort(v.begin(), v.end());
    v.resize(std::distance(v.begin(), unique(v.begin(), v.end())));
    sum += v.size();
    data_ptrs.push_back(&data[c]);
  }


  std::vector<std::vector<uint32_t>> range_boundaries;
  calc_alldata_boundaries(data, range_boundaries, range_size_avx512);
  std::vector<const std::vector<uint32_t>*> range_ptrs;
  for (size_t c = 0; c < array_count; c++) {
    range_ptrs.push_back(&range_boundaries[c]);
  }

  std::vector<int> evts = {
#ifdef __linux__
                           PERF_COUNT_HW_CPU_CYCLES,
                           PERF_COUNT_HW_INSTRUCTIONS,
                           PERF_COUNT_HW_BRANCH_MISSES,
                           PERF_COUNT_HW_CACHE_REFERENCES,
                           PERF_COUNT_HW_CACHE_MISSES
#endif
                          }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3d0, %rsp            # imm = 0x3D0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x320(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x318(%rbp)
callq 0x8860
movq -0x320(%rbp), %rsi
movq -0x318(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0x8880
jmp 0x57df
leaq -0x39(%rbp), %rdi
callq 0x88f0
leaq -0x68(%rbp), %rdi
callq 0x8510
leaq -0x80(%rbp), %rdi
movq %rdi, -0x328(%rbp)
callq 0x7ff0
movq -0x328(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x8010
jmp 0x5813
movq $0x0, -0x88(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x5a1d
movq -0x90(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x7f90
movq %rax, -0x98(%rbp)
movq $0x0, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x58e5
movq -0x98(%rbp), %rax
movq %rax, -0x330(%rbp)
callq 0x30a0
movq -0x330(%rbp), %rdi
cltq
movq -0x8(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, -0xa4(%rbp)
leaq -0xa4(%rbp), %rsi
callq 0x8910
jmp 0x58a4
jmp 0x58a6
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x585c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x88f0
jmp 0x6222
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x6207
movq -0x98(%rbp), %rdi
callq 0x8980
movq %rax, -0xb0(%rbp)
movq -0x98(%rbp), %rdi
callq 0x89b0
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0x8940
jmp 0x5920
movq -0x98(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0x8980
movq %rax, -0xc0(%rbp)
movq -0x98(%rbp), %rdi
callq 0x8980
movq %rax, -0xd0(%rbp)
movq -0x98(%rbp), %rdi
callq 0x89b0
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x8a20
movq %rax, -0x338(%rbp)
jmp 0x597c
movq -0x338(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xc0(%rbp), %rdi
movq -0xc8(%rbp), %rsi
callq 0x89e0
movq %rax, -0x348(%rbp)
jmp 0x59a6
movq -0x348(%rbp), %rsi
movq -0x340(%rbp), %rdi
callq 0x78a0
jmp 0x59bb
movq -0x98(%rbp), %rdi
callq 0x7a40
movq %rax, %rcx
movq -0x88(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x90(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x7f90
movq %rax, -0xe0(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x8610
jmp 0x5a04
jmp 0x5a06
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x5829
leaq -0xf8(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x84f0
movq -0x350(%rbp), %rsi
leaq -0x38(%rbp), %rdi
movl $0x9c40, %edx           # imm = 0x9C40
callq 0x40e0
jmp 0x5a47
leaq -0x110(%rbp), %rdi
callq 0x8510
movq $0x0, -0x118(%rbp)
movq -0x118(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x5ad2
movq -0x118(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x7f90
movq %rax, -0x120(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x8610
jmp 0x5a9a
jmp 0x5a9c
movq -0x118(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x118(%rbp)
jmp 0x5a5e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x61fb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x61ef
movups 0xe99f(%rip), %xmm0     # 0x14478
movaps %xmm0, -0x160(%rbp)
movl $0x3, -0x150(%rbp)
leaq -0x160(%rbp), %rax
movq %rax, -0x148(%rbp)
movq $0x5, -0x140(%rbp)
leaq -0x161(%rbp), %rdi
movq %rdi, -0x358(%rbp)
callq 0x8110
movq -0x358(%rbp), %rcx
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rdx
leaq -0x138(%rbp), %rdi
callq 0x8130
jmp 0x5b39
leaq -0x161(%rbp), %rdi
callq 0x81b0
leaq -0x1f0(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x81d0
jmp 0x5b5a
leaq -0x1d8(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x82c0
jmp 0x5b6f
leaq -0x1f0(%rbp), %rdi
callq 0x8490
movl $0x0, -0x1f4(%rbp)
movl $0x0, -0x1f8(%rbp)
movl $0x0, -0x1fc(%rbp)
movl $0x0, -0x200(%rbp)
movq -0x20(%rbp), %rdx
leaq -0x68(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3d00
jmp 0x5bb6
leaq -0x80(%rbp), %rdi
callq 0x7a40
movq %rax, -0x208(%rbp)
movq 0x183fb(%rip), %rdi     # 0x1dfc8
leaq 0xe535(%rip), %rsi      # 0x14109
callq 0x3280
movq %rax, -0x360(%rbp)
jmp 0x5be2
movq -0x360(%rbp), %rdi
movq -0x208(%rbp), %rsi
callq 0x3090
movq %rax, -0x368(%rbp)
jmp 0x5bfe
movq -0x368(%rbp), %rdi
leaq 0xe498(%rip), %rsi      # 0x140a4
callq 0x3280
jmp 0x5c13
imulq $0xa, -0x88(%rbp), %rax
movq %rax, -0x210(%rbp)
movq $0x0, -0x218(%rbp)
cmpq $0xa, -0x218(%rbp)
jae 0x5db2
movq -0x218(%rbp), %rax
subq $0x9, %rax
sete -0x219(%rbp)
leaq -0x68(%rbp), %rax
movq %rax, -0x238(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x230(%rbp)
leaq -0x20(%rbp), %rax
movq %rax, -0x228(%rbp)
leaq -0x259(%rbp), %rdi
movq %rdi, -0x370(%rbp)
callq 0x3480
movq -0x370(%rbp), %rdx
leaq 0xe41c(%rip), %rsi      # 0x140ab
leaq -0x258(%rbp), %rdi
callq 0x8660
jmp 0x5c9d
movq -0x88(%rbp), %r8
movq -0x208(%rbp), %r9
movzbl -0x219(%rbp), %ecx
movq -0x228(%rbp), %rdx
movq %rsp, %rax
movq %rdx, 0x10(%rax)
movups -0x238(%rbp), %xmm0
movups %xmm0, (%rax)
andl $0x1, %ecx
movl %ecx, 0x18(%rax)
leaq -0x258(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
leaq -0x1f4(%rbp), %rdx
leaq -0x80(%rbp), %rcx
callq 0x6230
jmp 0x5cf0
leaq -0x258(%rbp), %rdi
callq 0x31b0
leaq -0x259(%rbp), %rdi
callq 0x32e0
movq -0x218(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x218(%rbp)
jmp 0x5c2d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x161(%rbp), %rdi
callq 0x81b0
jmp 0x61ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x8490
jmp 0x61e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x61d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x5da1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x31b0
leaq -0x259(%rbp), %rdi
callq 0x32e0
jmp 0x61d7
movq $0x0, -0x268(%rbp)
cmpq $0xa, -0x268(%rbp)
jae 0x5fc2
movq -0x268(%rbp), %rax
subq $0x9, %rax
sete -0x269(%rbp)
leaq -0x68(%rbp), %rax
movq %rax, -0x288(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x280(%rbp)
leaq -0x20(%rbp), %rax
movq %rax, -0x278(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x37c(%rbp)
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x378(%rbp)
callq 0x3480
movq -0x378(%rbp), %rdx
leaq 0xe268(%rip), %rsi      # 0x14090
leaq -0x2a8(%rbp), %rdi
callq 0x8660
jmp 0x5e36
movl -0x37c(%rbp), %edx
movq -0x278(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movups -0x288(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x68(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x2a8(%rbp), %rcx
callq 0x6530
jmp 0x5e6a
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
leaq -0x2a9(%rbp), %rdi
callq 0x32e0
leaq -0x68(%rbp), %rax
movq %rax, -0x2c8(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x2c0(%rbp)
leaq -0x20(%rbp), %rax
movq %rax, -0x2b8(%rbp)
leaq -0x2e9(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x3480
movq -0x388(%rbp), %rdx
leaq 0xe1fa(%rip), %rsi      # 0x140be
leaq -0x2e8(%rbp), %rdi
callq 0x8660
jmp 0x5ed2
movq -0x88(%rbp), %r8
movq -0x208(%rbp), %r9
movzbl -0x269(%rbp), %ecx
movq -0x2b8(%rbp), %rdx
movq %rsp, %rax
movq %rdx, 0x10(%rax)
movups -0x2c8(%rbp), %xmm0
movups %xmm0, (%rax)
andl $0x1, %ecx
movl %ecx, 0x18(%rax)
leaq -0x2e8(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
leaq -0x1f8(%rbp), %rdx
leaq -0x80(%rbp), %rcx
callq 0x6920
jmp 0x5f25
leaq -0x2e8(%rbp), %rdi
callq 0x31b0
leaq -0x2e9(%rbp), %rdi
callq 0x32e0
movq -0x268(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x268(%rbp)
jmp 0x5dbd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x5f7a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
leaq -0x2a9(%rbp), %rdi
callq 0x32e0
jmp 0x61d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x5fb1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x31b0
leaq -0x2e9(%rbp), %rdi
callq 0x32e0
jmp 0x61d7
movq $0x0, -0x2f8(%rbp)
cmpq $0xa, -0x2f8(%rbp)
jae 0x5ffe
cmpq $0x9, -0x2f8(%rbp)
sete %al
andb $0x1, %al
movb %al, -0x2f9(%rbp)
movq -0x2f8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2f8(%rbp)
jmp 0x5fcd
movq $0x0, -0x308(%rbp)
cmpq $0xa, -0x308(%rbp)
jae 0x603a
cmpq $0x9, -0x308(%rbp)
sete %al
andb $0x1, %al
movb %al, -0x309(%rbp)
movq -0x308(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x308(%rbp)
jmp 0x6009
movq 0x17f87(%rip), %rdi     # 0x1dfc8
leaq 0xe09a(%rip), %rsi      # 0x140e2
callq 0x3280
movq %rax, -0x390(%rbp)
jmp 0x6056
movq -0x390(%rbp), %rdi
movq 0x17f44(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x606b
movq 0x17f56(%rip), %rdi     # 0x1dfc8
leaq 0xe084(%rip), %rsi      # 0x140fd
callq 0x3280
movq %rax, -0x398(%rbp)
jmp 0x6087
movq -0x398(%rbp), %rdi
movaps 0xdf7b(%rip), %xmm1     # 0x14010
movq -0x210(%rbp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xdf77(%rip), %xmm1     # 0x14020
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movss -0x1f4(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0xdf64(%rip), %xmm2     # 0x14030
divsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x34a0
movq %rax, -0x3a0(%rbp)
jmp 0x60e2
movq -0x3a0(%rbp), %rdi
movq 0x17eb8(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x60f7
movq 0x17eca(%rip), %rdi     # 0x1dfc8
leaq 0xdff4(%rip), %rsi      # 0x140f9
callq 0x3280
movq %rax, -0x3a8(%rbp)
jmp 0x6113
movq -0x3a8(%rbp), %rdi
movaps 0xdeef(%rip), %xmm1     # 0x14010
movq -0x210(%rbp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xdeeb(%rip), %xmm1     # 0x14020
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movss -0x1f8(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
movsd 0xded8(%rip), %xmm2     # 0x14030
divsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x34a0
movq %rax, -0x3b0(%rbp)
jmp 0x616e
movq -0x3b0(%rbp), %rdi
movq 0x17e2c(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x6183
leaq -0x1d8(%rbp), %rdi
callq 0x87d0
leaq -0x138(%rbp), %rdi
callq 0x8490
leaq -0x110(%rbp), %rdi
callq 0x8710
leaq -0xf8(%rbp), %rdi
callq 0x8770
leaq -0x80(%rbp), %rdi
callq 0x8800
leaq -0x68(%rbp), %rdi
callq 0x8710
leaq -0x38(%rbp), %rdi
callq 0x8770
addq $0x3d0, %rsp            # imm = 0x3D0
popq %rbp
retq
leaq -0x1d8(%rbp), %rdi
callq 0x87d0
leaq -0x138(%rbp), %rdi
callq 0x8490
leaq -0x110(%rbp), %rdi
callq 0x8710
leaq -0xf8(%rbp), %rdi
callq 0x8770
leaq -0x80(%rbp), %rdi
callq 0x8800
leaq -0x68(%rbp), %rdi
callq 0x8710
leaq -0x38(%rbp), %rdi
callq 0x8770
movq -0x48(%rbp), %rdi
callq 0x3470
nopl (%rax,%rax)