// File: /workspace/github_cpp_makefile_star2_O3/chahk0129[P]hash_bench/./bench/benchmark.hpp
// Function: benchmark_t<char [32]>::microbench(int, Pair<char [32]>*, int, bool)
inline void benchmark_t<Key_t>::microbench(int index_type, Pair<Key_t>* init_kv, int init_num, bool insert_only){
    Hash<Key_t>* hashtable = getInstance<Key_t>(index_type);
    gen_input(init_kv, init_num);
    /*
    if constexpr(sizeof(Key_t) > 8){
    }
    else{
	for(int i=0; i<init_num; i++){
	    init_kv[i].key = i+1;
	    init_kv[i].value = i+1;
	}
    }*/
    std::random_shuffle(init_kv, init_kv+init_num);
    clear_cache();
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    for(int i=0; i<init_num; i++){
	hashtable->Insert(init_kv[i].key, init_kv[i].value);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    uint64_t elapsed = end.tv_nsec - start.tv_nsec + (end.tv_sec - start.tv_sec)*1000000000;
    uint64_t throughput = (uint64_t)init_num / (elapsed/1000.0) * 1000000;
    std::cout << "\033[1;32m";
    std::cout << "Insert Throughput(Ops/sec): " << throughput << std::endl;
#ifdef BREAKDOWN
    std::cout << "Elapsed time(msec): " << elapsed/1000000.0 << "\033[0m" << std::endl;;
    std::cout << "split_time(msec): " << split_time/1000000.0 << std::endl;
    std::cout << "cuckoo_time(msec): " << cuckoo_time/1000000.0 << std::endl;
    std::cout << "traversal_time(msec): " << (elapsed - split_time - cuckoo_time)/1000000.0 << std::endl;
#endif
    if(insert_only)
	return;

    clear_cache();
    clock_gettime(CLOCK_MONOTONIC, &start);
    for(int i=0; i<init_num; i++){
	auto ret = hashtable->Get(init_kv[i].key);
	assert((uint64_t)ret == init_kv[i].value);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    elapsed = end.tv_nsec - start.tv_nsec + (end.tv_sec - start.tv_sec)*1000000000;
    throughput = (uint64_t)init_num / (elapsed/1000.0) * 1000000;
    std::cout << "\033[1;32m";
    std::cout << "Search Throughput(Ops/sec): " << throughput << "\033[0m" << std::endl;

    clear_cache();
    clock_gettime(CLOCK_MONOTONIC, &start);
    for(int i=0; i<init_num/30; i++){
	auto ret = hashtable->Update(init_kv[i].key, init_kv[i].value);
	assert(ret);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    elapsed = end.tv_nsec - start.tv_nsec + (end.tv_sec - start.tv_sec)*1000000000;
    throughput = (uint64_t)init_num/30 / (elapsed/1000.0) * 1000000;
    std::cout << "\033[1;32m";
    std::cout << "Update Throughput(Ops/sec): " << throughput << "\033[0m" << std::endl;

    clear_cache();
    clock_gettime(CLOCK_MONOTONIC, &start);
    for(int i=0; i<init_num/20; i++){
	auto ret = hashtable->Delete(init_kv[i].key);
	assert(ret);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    elapsed = end.tv_nsec - start.tv_nsec + (end.tv_sec - start.tv_sec)*1000000000;
    throughput = (uint64_t)(init_num/20) / (elapsed/1000.0) * 1000000;
    std::cout << "\033[1;32m";
    std::cout << "Delete Throughput(Ops/sec): " << throughput << "\033[0m" << std::endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %r8d, 0xc(%rsp)
movl %ecx, %ebp
movq %rdx, %rbx
movl %esi, %edi
callq 0x903d
movq %rax, %r14
movq %rbx, %rdi
movl %ebp, %esi
callq 0x90f6
movslq %ebp, %rcx
movq %rcx, (%rsp)
cmpl $0x2, %ecx
jb 0x7f7f
movq (%rsp), %rax
leaq (,%rax,8), %rax
leaq (%rax,%rax,4), %r15
movl $0x28, %r12d
movabsq $-0x3333333333333333, %r13 # imm = 0xCCCCCCCCCCCCCCCD
callq 0x2060
cltq
movq %r12, %rcx
sarq $0x3, %rcx
imulq %r13, %rcx
incq %rcx
cqto
idivq %rcx
shlq $0x3, %rdx
leaq (%rdx,%rdx,4), %rax
cmpq %rax, %r12
je 0x7f72
leaq (%rbx,%r12), %rcx
addq %rbx, %rax
movq 0x20(%rcx), %rdx
movq %rdx, 0x30(%rsp)
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movaps %xmm1, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movq 0x20(%rax), %rdx
movq %rdx, 0x20(%rcx)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%rcx)
movups %xmm0, (%rcx)
movq 0x30(%rsp), %rcx
movq %rcx, 0x20(%rax)
movaps 0x10(%rsp), %xmm0
movaps 0x20(%rsp), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
addq $0x28, %r12
cmpq %r12, %r15
jne 0x7efa
leaq 0x10(%rsp), %rsi
movl $0x1, %edi
callq 0x21b0
movl %ebp, %r12d
testl %ebp, %ebp
jle 0x7fb3
movq %r12, %r15
movq %rbx, %r13
movq 0x20(%r13), %rdx
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *(%rax)
addq $0x28, %r13
decq %r15
jne 0x7f9b
movq %r12, 0x38(%rsp)
leaq 0x40(%rsp), %r13
movl $0x1, %edi
movq %r13, %rsi
callq 0x21b0
movq 0x8(%r13), %rax
subq 0x18(%rsp), %rax
movq (%r13), %rcx
subq 0x10(%rsp), %rcx
imulq $0x3b9aca00, %rcx, %r15 # imm = 0x3B9ACA00
addq %rax, %r15
movsd (%rsp), %xmm0
movsd 0x604d(%rip), %xmm2     # 0xe040
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x6052(%rip), %xmm3     # 0xe050
subpd %xmm3, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movq %r15, %xmm0
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm3, %xmm0
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
movapd %xmm2, 0x60(%rsp)
movapd %xmm2, %xmm0
divsd 0x6057(%rip), %xmm0     # 0xe090
movapd %xmm1, 0x50(%rsp)
divsd %xmm0, %xmm1
mulsd 0x604d(%rip), %xmm1     # 0xe098
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x6041(%rip), %xmm1     # 0xe0a0
cvttsd2si %xmm1, %r12
andq %rcx, %r12
orq %rax, %r12
movq 0xcf4f(%rip), %r13      # 0x14fc0
leaq 0x61e5(%rip), %rsi      # 0xe25d
movl $0x7, %edx
movq %r13, %rdi
callq 0x2210
leaq 0x61d9(%rip), %rsi      # 0xe265
movl $0x1c, %edx
movq %r13, %rdi
callq 0x2210
movq %r13, %rdi
movq %r12, %rsi
callq 0x2110
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x61ad(%rip), %rsi      # 0xe282
movl $0x14, %edx
movq %r13, %rdi
callq 0x2210
movapd 0x60(%rsp), %xmm0
divsd 0x5fa8(%rip), %xmm0     # 0xe098
movq %r13, %rdi
callq 0x22d0
movq %rax, %r12
leaq 0x6195(%rip), %rsi      # 0xe297
movl $0x4, %edx
movq %rax, %rdi
callq 0x2210
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x615e(%rip), %rsi      # 0xe29c
movl $0x12, %edx
movq %r13, %rdi
callq 0x2210
movsd 0xd13d(%rip), %xmm1     # 0x15290
unpcklps 0x5ee6(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5eee(%rip), %xmm1     # 0xe050
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5f22(%rip), %xmm0     # 0xe098
movq %r13, %rdi
callq 0x22d0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x6100(%rip), %rsi      # 0xe2af
movl $0x13, %edx
movq %r13, %rdi
callq 0x2210
movsd 0xd0d4(%rip), %xmm1     # 0x15298
unpcklps 0x5e75(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5e7d(%rip), %xmm1     # 0xe050
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5eb1(%rip), %xmm0     # 0xe098
movq %r13, %rdi
callq 0x22d0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x60a3(%rip), %rsi      # 0xe2c3
movl $0x16, %edx
movq %r13, %rdi
callq 0x2210
movq 0xd05c(%rip), %rax      # 0x15290
addq 0xd05d(%rip), %rax      # 0x15298
subq %rax, %r15
movq %r15, %xmm1
punpckldq 0x5df5(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5dfd(%rip), %xmm1     # 0xe050
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5e31(%rip), %xmm0     # 0xe098
movq %r13, %rdi
callq 0x22d0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
cmpb $0x0, 0xc(%rsp)
jne 0x86ab
leaq 0x10(%rsp), %rsi
movl $0x1, %edi
callq 0x21b0
testl %ebp, %ebp
jle 0x82df
movq 0x38(%rsp), %r15
movq %rbx, %r12
movq (%r14), %rax
movq %r14, %rdi
movq %r12, %rsi
callq *0x18(%rax)
cmpq %rax, 0x20(%r12)
jne 0x86ba
addq $0x28, %r12
decq %r15
jne 0x82bf
leaq 0x40(%rsp), %r13
movl $0x1, %edi
movq %r13, %rsi
callq 0x21b0
movq 0x8(%r13), %rax
leaq 0x10(%rsp), %r12
subq 0x8(%r12), %rax
movq (%r13), %rcx
subq (%r12), %rcx
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
addq %rax, %rcx
movq %rcx, %xmm0
punpckldq 0x5d22(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x5d2a(%rip), %xmm0     # 0xe050
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
divsd 0x5d56(%rip), %xmm1     # 0xe090
movapd 0x50(%rsp), %xmm0
divsd %xmm1, %xmm0
mulsd 0x5d4c(%rip), %xmm0     # 0xe098
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5d40(%rip), %xmm0     # 0xe0a0
cvttsd2si %xmm0, %r13
andq %rcx, %r13
orq %rax, %r13
movq 0xcc4e(%rip), %r15      # 0x14fc0
leaq 0x5ee4(%rip), %rsi      # 0xe25d
movl $0x7, %edx
movq %r15, %rdi
callq 0x2210
leaq 0x5fde(%rip), %rsi      # 0xe36b
movl $0x1c, %edx
movq %r15, %rdi
callq 0x2210
movq %r15, %rdi
movq %r13, %rsi
callq 0x2110
movq %rax, %r15
leaq 0x5ee8(%rip), %rsi      # 0xe297
movl $0x4, %edx
movq %rax, %rdi
callq 0x2210
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x1, %edi
movq %r12, %rsi
callq 0x21b0
cmpl $0x1e, %ebp
jl 0x842a
movl $0x88888889, %r15d      # imm = 0x88888889
imulq 0x38(%rsp), %r15
shrq $0x24, %r15
movq %rbx, %r12
movq 0x20(%r12), %rdx
movq (%r14), %rax
movq %r14, %rdi
movq %r12, %rsi
callq *0x8(%rax)
testb %al, %al
je 0x86d9
addq $0x28, %r12
decq %r15
jne 0x8408
leaq 0x40(%rsp), %r15
movl $0x1, %edi
movq %r15, %rsi
callq 0x21b0
movabsq $-0x7777777777777777, %rcx # imm = 0x8888888888888889
movq (%rsp), %r12
movq %r12, %rax
mulq %rcx
movq 0x8(%r15), %rax
leaq 0x10(%rsp), %rsi
subq 0x8(%rsi), %rax
movq (%r15), %rcx
subq (%rsi), %rcx
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
shrq $0x4, %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
addq %rax, %rcx
movq %rcx, %xmm1
punpckldq 0x5bba(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5bc2(%rip), %xmm1     # 0xe050
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd 0x5bee(%rip), %xmm2     # 0xe090
divsd %xmm2, %xmm0
mulsd 0x5bea(%rip), %xmm0     # 0xe098
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5bde(%rip), %xmm0     # 0xe0a0
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
movq 0xcaec(%rip), %r13      # 0x14fc0
leaq 0x5d82(%rip), %rsi      # 0xe25d
movl $0x7, %edx
movq %r13, %rdi
callq 0x2210
leaq 0x5e9d(%rip), %rsi      # 0xe38c
movl $0x1c, %edx
movq %r13, %rdi
callq 0x2210
movq %r13, %rdi
movq %r15, %rsi
callq 0x2110
movq %rax, %r15
leaq 0x5d86(%rip), %rsi      # 0xe297
movl $0x4, %edx
movq %rax, %rdi
callq 0x2210
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x1, %edi
leaq 0x10(%rsp), %rsi
callq 0x21b0
imulq $0x66666667, %r12, %r15 # imm = 0x66666667
movq %r15, %rax
shrq $0x3f, %rax
sarq $0x23, %r15
addl %eax, %r15d
cmpl $0x14, %ebp
jl 0x858e
movl %r15d, %r12d
movq (%r14), %rax
movq %r14, %rdi
movq %rbx, %rsi
callq *0x10(%rax)
testb %al, %al
je 0x86f8
addq $0x28, %rbx
decq %r12
jne 0x8571
leaq 0x40(%rsp), %rbx
movl $0x1, %edi
movq %rbx, %rsi
callq 0x21b0
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq 0x18(%rsp), %rcx
subq 0x10(%rsp), %rax
imulq $0x3b9aca00, %rax, %rax # imm = 0x3B9ACA00
addq %rcx, %rax
movslq %r15d, %rcx
movq %rcx, %xmm0
movq 0x5a75(%rip), %xmm2     # 0xe040
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x5a79(%rip), %xmm3     # 0xe050
subpd %xmm3, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movq %rax, %xmm0
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm3, %xmm0
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
addsd %xmm0, %xmm2
divsd 0x5a88(%rip), %xmm2     # 0xe090
divsd %xmm2, %xmm1
mulsd 0x5a84(%rip), %xmm1     # 0xe098
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5a78(%rip), %xmm1     # 0xe0a0
cvttsd2si %xmm1, %rbx
andq %rcx, %rbx
orq %rax, %rbx
movq 0xc986(%rip), %r14      # 0x14fc0
leaq 0x5c1c(%rip), %rsi      # 0xe25d
movl $0x7, %edx
movq %r14, %rdi
callq 0x2210
leaq 0x5d54(%rip), %rsi      # 0xe3a9
movl $0x1c, %edx
movq %r14, %rdi
callq 0x2210
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2110
movq %rax, %rbx
leaq 0x5c20(%rip), %rsi      # 0xe297
movl $0x4, %edx
movq %rax, %rdi
callq 0x2210
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5c19(%rip), %rdi      # 0xe2da
leaq 0x5c34(%rip), %rsi      # 0xe2fc
leaq 0x5c43(%rip), %rcx      # 0xe312
movl $0xcb, %edx
callq 0x20f0
leaq 0x5ca8(%rip), %rdi      # 0xe388
leaq 0x5c15(%rip), %rsi      # 0xe2fc
leaq 0x5c24(%rip), %rcx      # 0xe312
movl $0xd7, %edx
callq 0x20f0
leaq 0x5c89(%rip), %rdi      # 0xe388
leaq 0x5bf6(%rip), %rsi      # 0xe2fc
leaq 0x5c05(%rip), %rcx      # 0xe312
movl $0xe3, %edx
callq 0x20f0
nop