// File: /workspace/github_cpp_makefile_star2_O2/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 $0x68, %rsp
movl %r8d, 0x24(%rsp)
movl %ecx, %r15d
movq %rdx, %rbx
movl %esi, %edi
callq 0x7304
movq %rax, %r14
movq %rbx, %rdi
movl %r15d, %esi
callq 0x73b6
movslq %r15d, %r12
imulq $0x28, %r12, %rsi
addq %rbx, %rsi
movq %rbx, %rdi
callq 0x7438
pushq $0x1
popq %rdi
leaq 0x10(%rsp), %rsi
callq 0x21b0
xorl %ebp, %ebp
testl %r12d, %r12d
movl %r15d, 0xc(%rsp)
cmovgl %r15d, %ebp
movq %rbx, %r13
movq %rbp, %r15
subq $0x1, %r15
jb 0x6644
movq 0x20(%r13), %rdx
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *(%rax)
addq $0x28, %r13
jmp 0x6629
pushq $0x1
popq %rdi
leaq 0x30(%rsp), %r13
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
movq %r12, 0x28(%rsp)
movq %r12, %xmm0
movq 0x598e(%rip), %xmm2     # 0xc010
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x5992(%rip), %xmm3     # 0xc020
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, 0x50(%rsp)
movapd %xmm2, %xmm0
divsd 0x5997(%rip), %xmm0     # 0xc060
movapd %xmm1, 0x40(%rsp)
divsd %xmm0, %xmm1
mulsd 0x598d(%rip), %xmm1     # 0xc068
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5981(%rip), %xmm1     # 0xc070
cvttsd2si %xmm1, %r12
andq %rcx, %r12
orq %rax, %r12
movq 0xd8bf(%rip), %r13      # 0x13fc0
leaq 0x5b1d(%rip), %rsi      # 0xc225
movq %r13, %rdi
callq 0x21d0
leaq 0x5b16(%rip), %rsi      # 0xc22d
movq %r13, %rdi
callq 0x21d0
movq %rax, %rdi
movq %r12, %rsi
callq 0x2110
movq %rax, %rdi
callq 0x20c0
leaq 0x5b11(%rip), %rsi      # 0xc24a
movq %r13, %rdi
callq 0x21d0
movapd 0x50(%rsp), %xmm0
divsd 0x5919(%rip), %xmm0     # 0xc068
movq %rax, %rdi
callq 0x22e0
leaq 0x5b01(%rip), %rsi      # 0xc25f
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
leaq 0x5aef(%rip), %rsi      # 0xc264
movq %r13, %rdi
callq 0x21d0
movsd 0xdb1b(%rip), %xmm1     # 0x142a0
unpcklps 0x5884(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x588c(%rip), %xmm1     # 0xc020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x58c0(%rip), %xmm0     # 0xc068
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
leaq 0x5ab8(%rip), %rsi      # 0xc277
movq %r13, %rdi
callq 0x21d0
movsd 0xdad9(%rip), %xmm1     # 0x142a8
unpcklps 0x583a(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x5842(%rip), %xmm1     # 0xc020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x5876(%rip), %xmm0     # 0xc068
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
leaq 0x5a82(%rip), %rsi      # 0xc28b
movq %r13, %rdi
callq 0x21d0
movq 0xda88(%rip), %rcx      # 0x142a0
addq 0xda89(%rip), %rcx      # 0x142a8
subq %rcx, %r15
movq %r15, %xmm1
punpckldq 0x57e1(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x57e9(%rip), %xmm1     # 0xc020
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
divsd 0x581d(%rip), %xmm0     # 0xc068
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
cmpb $0x0, 0x24(%rsp)
jne 0x6c11
pushq $0x1
popq %rdi
leaq 0x10(%rsp), %rsi
callq 0x21b0
incq %rbp
movq %rbx, %r12
decq %rbp
je 0x68b8
leaq 0x28(%r12), %r15
movq (%r14), %rax
movq %r14, %rdi
movq %r12, %rsi
callq *0x18(%rax)
cmpq %rax, 0x20(%r12)
movq %r15, %r12
je 0x6879
leaq 0x5a02(%rip), %rdi      # 0xc2a2
leaq 0x5a1d(%rip), %rsi      # 0xc2c4
leaq 0x5a2c(%rip), %rcx      # 0xc2da
movl $0xcb, %edx
callq 0x20f0
pushq $0x1
popq %r15
leaq 0x30(%rsp), %r12
movl %r15d, %edi
movq %r12, %rsi
callq 0x21b0
movq 0x8(%r12), %rax
leaq 0x10(%rsp), %r13
subq 0x8(%r13), %rax
movq (%r12), %rcx
subq (%r13), %rcx
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
addq %rax, %rcx
movq %rcx, %xmm0
punpckldq 0x5717(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x571f(%rip), %xmm0     # 0xc020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
divsd 0x574b(%rip), %xmm1     # 0xc060
movapd 0x40(%rsp), %xmm0
divsd %xmm1, %xmm0
mulsd 0x5741(%rip), %xmm0     # 0xc068
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x5735(%rip), %xmm0     # 0xc070
cvttsd2si %xmm0, %r12
andq %rcx, %r12
orq %rax, %r12
movq 0xd673(%rip), %rbp      # 0x13fc0
leaq 0x58d1(%rip), %rsi      # 0xc225
movq %rbp, %rdi
callq 0x21d0
leaq 0x59d0(%rip), %rsi      # 0xc333
movq %rbp, %rdi
callq 0x21d0
movq %rax, %rdi
movq %r12, %rsi
callq 0x2110
leaq 0x58e2(%rip), %rsi      # 0xc25f
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movl %r15d, %edi
movq %r13, %rsi
callq 0x21b0
pushq $0x1e
popq %rcx
movl 0xc(%rsp), %eax
cltd
idivl %ecx
xorl %r15d, %r15d
testl %eax, %eax
cmovgl %eax, %r15d
incq %r15
movq %rbx, %rsi
decq %r15
je 0x69ed
leaq 0x28(%rsi), %r12
movq 0x20(%rsi), %rdx
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
movq %r12, %rsi
testb %al, %al
jne 0x69b1
leaq 0x597b(%rip), %rdi      # 0xc350
leaq 0x58e8(%rip), %rsi      # 0xc2c4
leaq 0x58f7(%rip), %rcx      # 0xc2da
movl $0xd7, %edx
callq 0x20f0
pushq $0x1
popq %rdi
leaq 0x30(%rsp), %rbp
movq %rbp, %rsi
callq 0x21b0
movq 0x8(%rbp), %rax
leaq 0x10(%rsp), %r13
subq 0x8(%r13), %rax
movq (%rbp), %rcx
subq (%r13), %rcx
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
addq %rax, %rcx
pushq $0x1e
popq %rsi
movq 0x28(%rsp), %rax
xorl %edx, %edx
divq %rsi
cvtsi2sd %rax, %xmm0
xorl %r12d, %r12d
movq %rcx, %xmm1
punpckldq 0x55d2(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x55da(%rip), %xmm1     # 0xc020
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd 0x5606(%rip), %xmm2     # 0xc060
divsd %xmm2, %xmm0
mulsd 0x5602(%rip), %xmm0     # 0xc068
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x55f6(%rip), %xmm0     # 0xc070
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
movq 0xd534(%rip), %rbp      # 0x13fc0
leaq 0x5792(%rip), %rsi      # 0xc225
movq %rbp, %rdi
callq 0x21d0
leaq 0x58b2(%rip), %rsi      # 0xc354
movq %rbp, %rdi
callq 0x21d0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2110
leaq 0x57a3(%rip), %rsi      # 0xc25f
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
pushq $0x1
popq %rdi
movq %r13, %rsi
callq 0x21b0
pushq $0x14
popq %rcx
movl 0xc(%rsp), %eax
cltd
idivl %ecx
movl %eax, %ebp
testl %eax, %eax
cmovgl %eax, %r12d
incq %r12
decq %r12
je 0x6b27
leaq 0x28(%rbx), %r15
movq (%r14), %rax
movq %r14, %rdi
movq %rbx, %rsi
callq *0x10(%rax)
movq %r15, %rbx
testb %al, %al
jne 0x6aec
leaq 0x5841(%rip), %rdi      # 0xc350
leaq 0x57ae(%rip), %rsi      # 0xc2c4
leaq 0x57bd(%rip), %rcx      # 0xc2da
movl $0xe3, %edx
callq 0x20f0
pushq $0x1
popq %rdi
leaq 0x30(%rsp), %rbx
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 %ebp, %rcx
movq %rcx, %xmm0
movq 0x54ae(%rip), %xmm2     # 0xc010
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movapd 0x54b2(%rip), %xmm3     # 0xc020
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 0x54c1(%rip), %xmm2     # 0xc060
divsd %xmm2, %xmm1
mulsd 0x54bd(%rip), %xmm1     # 0xc068
cvttsd2si %xmm1, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x54b1(%rip), %xmm1     # 0xc070
cvttsd2si %xmm1, %rbx
andq %rcx, %rbx
orq %rax, %rbx
movq 0xd3ef(%rip), %r14      # 0x13fc0
leaq 0x564d(%rip), %rsi      # 0xc225
movq %r14, %rdi
callq 0x21d0
leaq 0x578a(%rip), %rsi      # 0xc371
movq %r14, %rdi
callq 0x21d0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2110
leaq 0x565e(%rip), %rsi      # 0xc25f
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq