// File: /workspace/github_cpp_makefile_star2_O3/narges64[P]SIMBA/ssd.cpp
// Function: print_statistics(ssd_info*, int)
void print_statistics(ssd_info *ssd, int app){

	fprintf(ssd->statisticfile, "======== Application %d , time %lld ============ \n", app, ssd->total_execution_time);

	fprintf(ssd->statisticfile, "request read RT avg %lld us , var %lld ms2 , count %lld , max %lld us\n", 
									ssd->stats->read_RT.get_average(), ssd->stats->read_RT.get_variance(), 
									ssd->stats->read_RT.get_count() , ssd->stats->read_RT.get_max());

	fprintf(ssd->statisticfile, "request write RT avg %lld us , var %lld ms2, count %lld , max %lld us \n", 
									ssd->stats->write_RT.get_average(), ssd->stats->write_RT.get_variance(), 
									ssd->stats->write_RT.get_count() , ssd->stats->write_RT.get_max());
	
	fprintf(ssd->statisticfile, "read IOPS and BW [%d]: %f , %f  \n", app, ssd->stats->read_throughput.get_IOPS() , ssd->stats->read_throughput.get_BW());
	fprintf(ssd->statisticfile, "write IOPS and BW [%d]: %f , %f  \n", app, ssd->stats->write_throughput.get_IOPS() , ssd->stats->write_throughput.get_BW());

	fprintf(ssd->statisticfile,"erase: ( %lld )\n", ssd->stats->total_flash_erase_count);
	fprintf(ssd->statisticfile,"total gc move count: %d \n", ssd->stats->gc_moved_page);
	fprintf(ssd->statisticfile, "buffer read hit %d , write hit %d , gc buffer read hit %d , write hit %d \n ", 
								ssd->dram->buffer->read_hit , ssd->dram->buffer->write_hit , 
								ssd->dram->gc_buffer->read_hit , ssd->dram->gc_buffer->write_hit); 

	fprintf(ssd->statisticfile, "flash program count %d , WAF %f\n" , ssd->stats->flash_prog_count , (ssd->stats->flash_prog_count)/(double)(ssd->stats->flash_prog_count - ssd->stats->gc_moved_page));  

	fprintf(ssd->statisticfile, "========================\n");

	ssd->stats->flash_erase_count = 0;

	// Print lun statistic output
	int chan,lun = 0;
	/*


	fprintf(ssd->statisticfile, "\nlun IOPS \n");
	for (chan = 0; chan < ssd->parameter->channel_number; chan++){
		for (lun = 0; lun < ssd->channel_head[chan]->lun_num; lun++){
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_read_throughput.get_IOPS());
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_write_throughput.get_IOPS());
			fprintf(ssd->statisticfile, "%d\t", (int)ssd->channel_head[chan]->lun_head[lun]->stat_rw_throughput.get_IOPS());
		}
		fprintf(ssd->statisticfile, "\n");
	}

	fprintf(ssd->statisticfile, "\nlun BW  (MB/s) \n");
	for (chan = 0; chan < ssd->parameter->channel_number; chan++){
		for (lun = 0; lun < ssd->channel_head[chan]->lun_num; lun++){
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_read_throughput.get_BW());
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_write_throughput.get_BW());
			fprintf(ssd->statisticfile, "%d\t", (int)ssd->channel_head[chan]->lun_head[lun]->stat_rw_throughput.get_BW());
		}
		fprintf(ssd->statisticfile, "\n");
	}

	fprintf(ssd->statisticfile, "\nlun noop IOPS \n");
	for (chan = 0; chan < ssd->parameter->channel_number; chan++){
		for (lun = 0; lun < ssd->channel_head[chan]->lun_num; lun++){
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_read_throughput.get_noop_IOPS());
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_write_throughput.get_noop_IOPS());
			fprintf(ssd->statisticfile, "%d\t", (int)ssd->channel_head[chan]->lun_head[lun]->stat_rw_throughput.get_noop_IOPS());
		}
		fprintf(ssd->statisticfile, "\n");
	}


	fprintf(ssd->statisticfile, "\nlun noop BW (MB/s) \n");
	for (chan = 0; chan < ssd->parameter->channel_number; chan++){
		for (lun = 0; lun < ssd->channel_head[chan]->lun_num; lun++){
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_read_throughput.get_noop_BW());
			fprintf(ssd->statisticfile, "%d,", (int)ssd->channel_head[chan]->lun_head[lun]->stat_write_throughput.get_noop_BW());
			fprintf(ssd->statisticfile, "%d\t", (int)ssd->channel_head[chan]->lun_head[lun]->stat_rw_throughput.get_noop_BW());
		}
		fprintf(ssd->statisticfile, "\n");
	}
	*/

	fprintf(ssd->statisticfile, "\nlun erase count \n");
	for (chan = 0; chan < ssd->parameter->channel_number; chan++){
		for (lun = 0; lun < ssd->channel_head[chan]->lun_num; lun++){
			fprintf(ssd->statisticfile, "%d\t", ssd->channel_head[chan]->lun_head[lun]->erase_count);
		}
		fprintf(ssd->statisticfile, "\n");
	}

	fprintf(ssd->statisticfile, "\nplanes erase number: \n");
	for(int i=0;i<ssd->parameter->channel_number;i++){
		for (int j = 0; j < ssd->parameter->lun_channel[i]; j++){
			for(int l=0;l<ssd->parameter->plane_lun;l++)
			{
				int plane_erase = ssd->channel_head[i]->lun_head[j]->plane_head[l]->erase_count;
				fprintf(ssd->statisticfile,"(%d,%d)",l, plane_erase);
			}
			fprintf(ssd->statisticfile, "\t");
		}
		fprintf(ssd->statisticfile, "\n");
	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %ebp
movq %rdi, %rbx
movq 0x28(%rdi), %rcx
movq 0x50(%rdi), %rdi
leaq 0x2860(%rip), %rsi      # 0xae66
xorl %r14d, %r14d
movl %ebp, %edx
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rsi
movslq 0x8(%rsi), %r8
movabsq $0x20c49ba5e353f7cf, %r12 # imm = 0x20C49BA5E353F7CF
testq %r8, %r8
je 0x8668
movq 0x10(%rsi), %rax
movq 0x18(%rsi), %rcx
cqto
idivq %r8
movq %rax, %r14
movq %rcx, %rax
cqto
idivq %r8
movq %rax, %rcx
movq %r14, %rax
imulq %r12
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x7, %rdx
addq %rax, %rdx
imulq %rdx, %rdx
subq %rdx, %rcx
jmp 0x866a
xorl %ecx, %ecx
movq 0x20(%rsi), %r9
leaq 0x2824(%rip), %rsi      # 0xae99
xorl %r15d, %r15d
movq %r14, %rdx
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rsi
movslq 0x30(%rsi), %r8
testq %r8, %r8
je 0x86ce
movq 0x38(%rsi), %rax
movq 0x40(%rsi), %rcx
cqto
idivq %r8
movq %rax, %r15
movq %rcx, %rax
cqto
idivq %r8
movq %rax, %rcx
movq %r15, %rax
imulq %r12
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x7, %rdx
addq %rax, %rdx
imulq %rdx, %rdx
subq %rdx, %rcx
jmp 0x86d0
xorl %ecx, %ecx
movq 0x48(%rsi), %r9
leaq 0x2805(%rip), %rsi      # 0xaee0
movq %r15, %rdx
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rcx
movq 0x190(%rcx), %rax
xorpd %xmm1, %xmm1
testq %rax, %rax
je 0x873a
cvtsi2sdq 0x1a0(%rcx), %xmm0
xorps %xmm1, %xmm1
cvtsi2sdq 0x198(%rcx), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
mulpd 0x24cf(%rip), %xmm1     # 0xabf0
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
shlq $0xb, %rax
cvtsi2sd %rax, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
divpd %xmm2, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
leaq 0x27df(%rip), %rsi      # 0xaf28
movl %ebp, %edx
movb $0x2, %al
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rcx
movq 0x1b0(%rcx), %rax
testq %rax, %rax
xorpd %xmm1, %xmm1
je 0x87ad
xorps %xmm0, %xmm0
cvtsi2sdq 0x1c0(%rcx), %xmm0
xorps %xmm1, %xmm1
cvtsi2sdq 0x1b8(%rcx), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
mulpd 0x245f(%rip), %xmm1     # 0xabf0
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
shlq $0xb, %rax
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
divpd %xmm2, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
leaq 0x278e(%rip), %rsi      # 0xaf4a
movl %ebp, %edx
movb $0x2, %al
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rax
movq 0xa0(%rax), %rdx
leaq 0x278f(%rip), %rsi      # 0xaf6d
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rax
movl 0xc8(%rax), %edx
leaq 0x2781(%rip), %rsi      # 0xaf7e
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x60(%rbx), %rax
movq 0x18(%rax), %rcx
movq 0x20(%rax), %rax
movl (%rcx), %edx
movl 0x4(%rcx), %ecx
movl (%rax), %r8d
movl 0x4(%rax), %r9d
leaq 0x2771(%rip), %rsi      # 0xaf98
xorl %eax, %eax
callq 0x2280
movq 0x50(%rbx), %rdi
movq 0x98(%rbx), %rax
movq 0x88(%rax), %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
movslq 0xc8(%rax), %rax
movq %rdx, %rcx
subq %rax, %rcx
xorps %xmm1, %xmm1
cvtsi2sd %rcx, %xmm1
divsd %xmm1, %xmm0
leaq 0x277c(%rip), %rsi      # 0xafe4
movb $0x1, %al
callq 0x2280
movq 0x50(%rbx), %rcx
leaq 0x278b(%rip), %rdi      # 0xb005
movl $0x19, %esi
movl $0x1, %edx
callq 0x2310
movq 0x98(%rbx), %rax
movq $0x0, 0x98(%rax)
movq 0x50(%rbx), %rcx
leaq 0x2779(%rip), %rdi      # 0xb01f
movl $0x12, %esi
movl $0x1, %edx
callq 0x2310
movq 0x58(%rbx), %rax
cmpl $0x0, 0x98(%rax)
je 0x892e
leaq 0x2769(%rip), %r14      # 0xb032
xorl %r15d, %r15d
movq 0x90(%rbx), %rax
movq (%rax,%r15,8), %rax
cmpl $0x0, (%rax)
jle 0x890e
xorl %r12d, %r12d
movq 0x50(%rbx), %rdi
movq 0x50(%rax), %rax
movq (%rax,%r12,8), %rax
movl 0x8(%rax), %edx
movq %r14, %rsi
xorl %eax, %eax
callq 0x2280
incq %r12
movq 0x90(%rbx), %rax
movq (%rax,%r15,8), %rax
movslq (%rax), %rcx
cmpq %rcx, %r12
jl 0x88df
movq 0x50(%rbx), %rsi
movl $0xa, %edi
callq 0x2220
incq %r15
movq 0x58(%rbx), %rax
movl 0x98(%rax), %eax
cmpq %rax, %r15
jb 0x88cc
movq 0x50(%rbx), %rcx
leaq 0x26fd(%rip), %rdi      # 0xb036
movl $0x17, %esi
movl $0x1, %edx
callq 0x2310
movq 0x58(%rbx), %rax
cmpl $0x0, 0x98(%rax)
je 0x8a03
leaq 0x26ee(%rip), %r14      # 0xb04e
xorl %r12d, %r12d
cmpl $0x0, 0x9c(%rax,%r12,4)
je 0x89df
xorl %r13d, %r13d
cmpl $0x0, 0x22c(%rax)
je 0x89bd
xorl %r15d, %r15d
movq 0x50(%rbx), %rdi
movq 0x90(%rbx), %rax
movq (%rax,%r12,8), %rax
movq 0x50(%rax), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rax
movq (%rax,%r15,8), %rax
movl 0x30(%rax), %ecx
movq %r14, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x2280
incq %r15
movq 0x58(%rbx), %rax
movl 0x22c(%rax), %eax
cmpq %rax, %r15
jb 0x897d
movq 0x50(%rbx), %rsi
movl $0x9, %edi
callq 0x2220
incq %r13
movq 0x58(%rbx), %rax
movl 0x9c(%rax,%r12,4), %ecx
cmpq %rcx, %r13
jb 0x8971
movq 0x50(%rbx), %rsi
movl $0xa, %edi
callq 0x2220
incq %r12
movq 0x58(%rbx), %rax
movl 0x98(%rax), %ecx
cmpq %rcx, %r12
jb 0x8963
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq