// File: /workspace/github_cpp_makefile_star2_O1/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 0x825d
movq %rax, %r14
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8316
movslq %ebp, %rcx
movq %rcx, (%rsp)
cmpl $0x2, %ecx
jb 0x71af
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 0x71a2
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 0x712a
leaq 0x10(%rsp), %rsi
movl $0x1, %edi
callq 0x21b0
movl %ebp, %r12d
testl %ebp, %ebp
jle 0x71e3
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 0x71cb
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 0x5ded(%rip), %xmm2     # 0xd010
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x5df2(%rip), %xmm3     # 0xd020
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 0x5de7(%rip), %xmm0     # 0xd050
movapd %xmm1, 0x50(%rsp)
divsd %xmm0, %xmm1
mulsd 0x5ddd(%rip), %xmm1     # 0xd058
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5dd1(%rip), %xmm1     # 0xd060
cvttsd2si %xmm1, %r12
andq %rcx, %r12
orq %rax, %r12
movq 0xcd1f(%rip), %r13      # 0x13fc0
leaq 0x5f75(%rip), %rsi      # 0xd21d
movl $0x7, %edx
movq %r13, %rdi
callq 0x2210
leaq 0x5f69(%rip), %rsi      # 0xd225
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 0x5f3d(%rip), %rsi      # 0xd242
movl $0x14, %edx
movq %r13, %rdi
callq 0x2210
movapd 0x60(%rsp), %xmm0
divsd 0x5d38(%rip), %xmm0     # 0xd058
movq %r13, %rdi
callq 0x22d0
movq %rax, %r12
leaq 0x5f25(%rip), %rsi      # 0xd257
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 0x5eee(%rip), %rsi      # 0xd25c
movl $0x12, %edx
movq %r13, %rdi
callq 0x2210
movsd 0xcf0d(%rip), %xmm1     # 0x14290
unpcklps 0x5c86(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5c8e(%rip), %xmm1     # 0xd020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5cb2(%rip), %xmm0     # 0xd058
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 0x5e90(%rip), %rsi      # 0xd26f
movl $0x13, %edx
movq %r13, %rdi
callq 0x2210
movsd 0xcea4(%rip), %xmm1     # 0x14298
unpcklps 0x5c15(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5c1d(%rip), %xmm1     # 0xd020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5c41(%rip), %xmm0     # 0xd058
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 0x5e33(%rip), %rsi      # 0xd283
movl $0x16, %edx
movq %r13, %rdi
callq 0x2210
movq 0xce2c(%rip), %rax      # 0x14290
addq 0xce2d(%rip), %rax      # 0x14298
subq %rax, %r15
movq %r15, %xmm1
punpckldq 0x5b95(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5b9d(%rip), %xmm1     # 0xd020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5bc1(%rip), %xmm0     # 0xd058
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 0x78db
leaq 0x10(%rsp), %rsi
movl $0x1, %edi
callq 0x21b0
testl %ebp, %ebp
jle 0x750f
movq 0x38(%rsp), %r15
movq %rbx, %r12
movq (%r14), %rax
movq %r14, %rdi
movq %r12, %rsi
callq *0x18(%rax)
cmpq %rax, 0x20(%r12)
jne 0x78ea
addq $0x28, %r12
decq %r15
jne 0x74ef
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 0x5ac2(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x5aca(%rip), %xmm0     # 0xd020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
divsd 0x5ae6(%rip), %xmm1     # 0xd050
movapd 0x50(%rsp), %xmm0
divsd %xmm1, %xmm0
mulsd 0x5adc(%rip), %xmm0     # 0xd058
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5ad0(%rip), %xmm0     # 0xd060
cvttsd2si %xmm0, %r13
andq %rcx, %r13
orq %rax, %r13
movq 0xca1e(%rip), %r15      # 0x13fc0
leaq 0x5c74(%rip), %rsi      # 0xd21d
movl $0x7, %edx
movq %r15, %rdi
callq 0x2210
leaq 0x5d6e(%rip), %rsi      # 0xd32b
movl $0x1c, %edx
movq %r15, %rdi
callq 0x2210
movq %r15, %rdi
movq %r13, %rsi
callq 0x2110
movq %rax, %r15
leaq 0x5c78(%rip), %rsi      # 0xd257
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 0x765a
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 0x7909
addq $0x28, %r12
decq %r15
jne 0x7638
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 0x595a(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5962(%rip), %xmm1     # 0xd020
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd 0x597e(%rip), %xmm2     # 0xd050
divsd %xmm2, %xmm0
mulsd 0x597a(%rip), %xmm0     # 0xd058
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x596e(%rip), %xmm0     # 0xd060
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
movq 0xc8bc(%rip), %r13      # 0x13fc0
leaq 0x5b12(%rip), %rsi      # 0xd21d
movl $0x7, %edx
movq %r13, %rdi
callq 0x2210
leaq 0x5c2d(%rip), %rsi      # 0xd34c
movl $0x1c, %edx
movq %r13, %rdi
callq 0x2210
movq %r13, %rdi
movq %r15, %rsi
callq 0x2110
movq %rax, %r15
leaq 0x5b16(%rip), %rsi      # 0xd257
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 0x77be
movl %r15d, %r12d
movq (%r14), %rax
movq %r14, %rdi
movq %rbx, %rsi
callq *0x10(%rax)
testb %al, %al
je 0x7928
addq $0x28, %rbx
decq %r12
jne 0x77a1
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 0x5815(%rip), %xmm2     # 0xd010
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x5819(%rip), %xmm3     # 0xd020
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 0x5818(%rip), %xmm2     # 0xd050
divsd %xmm2, %xmm1
mulsd 0x5814(%rip), %xmm1     # 0xd058
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5808(%rip), %xmm1     # 0xd060
cvttsd2si %xmm1, %rbx
andq %rcx, %rbx
orq %rax, %rbx
movq 0xc756(%rip), %r14      # 0x13fc0
leaq 0x59ac(%rip), %rsi      # 0xd21d
movl $0x7, %edx
movq %r14, %rdi
callq 0x2210
leaq 0x5ae4(%rip), %rsi      # 0xd369
movl $0x1c, %edx
movq %r14, %rdi
callq 0x2210
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2110
movq %rax, %rbx
leaq 0x59b0(%rip), %rsi      # 0xd257
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 0x59a9(%rip), %rdi      # 0xd29a
leaq 0x59c4(%rip), %rsi      # 0xd2bc
leaq 0x59d3(%rip), %rcx      # 0xd2d2
movl $0xcb, %edx
callq 0x20f0
leaq 0x5a38(%rip), %rdi      # 0xd348
leaq 0x59a5(%rip), %rsi      # 0xd2bc
leaq 0x59b4(%rip), %rcx      # 0xd2d2
movl $0xd7, %edx
callq 0x20f0
leaq 0x5a19(%rip), %rdi      # 0xd348
leaq 0x5986(%rip), %rsi      # 0xd2bc
leaq 0x5995(%rip), %rcx      # 0xd2d2
movl $0xe3, %edx
callq 0x20f0
nop