6 Star 4 Fork 3

ZhouHeyu / simulation

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Interface.c 20.90 KB
一键复制 编辑 原始数据 按行查看 历史
ZhouHeyu 提交于 2020-08-16 17:52 . Description:flash接口整理
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
//
// Created by zhouheyu on 17-12-27.
//
#include "global.h"
#include "Interface.h"
#include "flash.h"
#include "fast.h"
#include "dftl.h"
#include "LRU.h"
#include "CFLRU.h"
#include "CASA.h"
#include "FAB.h"
#include "ADLRU.h"
#include "LRUWSR.h"
#include "CCFLRU.h"
#include "BPLRU.h"
#include "ADCT.h"
#include "HotDataAware.h"
#include "pure_ADCT.h"
int old_merge_switch_num = 0;
int old_merge_partial_num = 0;
int old_merge_full_num= 0;
int old_flash_gc_read_num = 0;
int old_flash_erase_num = 0;
int req_count_num = 1;
int rqst_cnt;
int flag1 = 1;
int count = 0;
//二级映射地址的大小
int page_num_for_2nd_map_table;
#define MAP_REAL_MAX_ENTRIES 6552// real map table size in bytes
#define MAP_GHOST_MAX_ENTRIES 1640// ghost_num is no of entries chk if this is ok
int ghost_arr[MAP_GHOST_MAX_ENTRIES];
int real_arr[MAP_REAL_MAX_ENTRIES];
/***********************************************************************
Variables for statistics
***********************************************************************/
unsigned int cnt_read = 0;
unsigned int cnt_write = 0;
unsigned int cnt_delete = 0;
unsigned int cnt_evict_from_flash = 0;
unsigned int cnt_evict_into_disk = 0;
unsigned int cnt_fetch_miss_from_disk = 0;
unsigned int cnt_fetch_miss_into_flash = 0;
double sum_of_queue_time = 0.0;
double sum_of_service_time = 0.0;
double sum_of_response_time = 0.0;
unsigned int total_num_of_req = 0;
/***********************************************************************
Mapping table
***********************************************************************/
int real_min = -1;
int real_max = 0;
// Interface between disksim & fsim
void reset_flash_stat()
{
flash_read_num = 0;
flash_write_num = 0;
flash_gc_read_num = 0;
flash_gc_write_num = 0;
flash_erase_num = 0;
flash_oob_read_num = 0;
flash_oob_write_num = 0;
}
FILE *fp_flash_stat;
FILE *fp_gc;
FILE *fp_gc_timeseries;
double gc_di =0 ,gc_ti=0;
double calculate_delay_flash()
{
double delay;
double read_delay, write_delay;
double erase_delay;
double gc_read_delay, gc_write_delay;
double oob_write_delay, oob_read_delay;
oob_read_delay = (double)OOB_READ_DELAY * flash_oob_read_num;
oob_write_delay = (double)OOB_WRITE_DELAY * flash_oob_write_num;
read_delay = (double)READ_DELAY * flash_read_num;
write_delay = (double)WRITE_DELAY * flash_write_num;
erase_delay = (double)ERASE_DELAY * flash_erase_num;
gc_read_delay = (double)GC_READ_DELAY * flash_gc_read_num;
gc_write_delay = (double)GC_WRITE_DELAY * flash_gc_write_num;
delay = read_delay + write_delay + erase_delay + gc_read_delay + gc_write_delay +
oob_read_delay + oob_write_delay;
// 统计垃圾回收的时间开销
// if( flash_gc_read_num > 0 || flash_gc_write_num > 0 || flash_erase_num > 0 ) {
// gc_ti += delay;
// }
// else {
// gc_di += delay;
// }
//
// if(warm_done == 1){
// fprintf(fp_gc_timeseries, "%d\t%d\t%d\t%d\t%d\t%d\n",
// req_count_num, merge_switch_num - old_merge_switch_num,
// merge_partial_num - old_merge_partial_num,
// merge_full_num - old_merge_full_num,
// flash_gc_read_num,
// flash_erase_num);
//
// old_merge_switch_num = merge_switch_num;
// old_merge_partial_num = merge_partial_num;
// old_merge_full_num = merge_full_num;
// req_count_num++;
// }
reset_flash_stat();
return delay;
}
/***********************************************************************
Initialize Flash Drive
***********************************************************************/
void initFlash()
{
blk_t total_blk_num;
blk_t total_util_blk_num;
blk_t total_extr_blk_num;
// total number of sectors
total_util_sect_num = flash_numblocks;
total_extra_sect_num = flash_extrblocks;
total_sect_num = total_util_sect_num + total_extra_sect_num;
// total number of blocks
total_blk_num = total_sect_num / SECT_NUM_PER_BLK; // total block number
total_util_blk_num = total_util_sect_num / SECT_NUM_PER_BLK; // total unique block number
global_total_blk_num = total_util_blk_num;
total_extr_blk_num = total_blk_num - total_util_blk_num; // total extra block number
ASSERT(total_extr_blk_num != 0);
if (nand_init(total_blk_num, 4) < 0) {
EXIT(-4);
}
// 选择相应的FTL算法
switch(ftl_type){
// // pagemap
// case 1: ftl_op = pm_setup(); break;
// // blockmap
// //case 2: ftl_op = bm_setup(); break;
// // o-pagemap
case 3: ftl_op = opm_setup(); break;
// // fast
case 4: ftl_op = lm_setup(); break;
default: break;
}
// 选择相应的缓冲区算法
switch(cache_type){
// LRU
case 1: cache_op=LRU_op_setup();break;
// CFLRU
case 2: cache_op=CFLRU_op_setup();break;
// AD-LRU
case 3: cache_op=ADLRU_op_setup();break;
// CASA
case 4: cache_op=CASA_op_setup();break;
// LRU-WSR
case 5: cache_op=LRUWSR_op_setup();break;
// CCF-LRU
case 6:cache_op=CCFLRU_op_setup();break;
// 块级的FAB算法
case 7:cache_op=FAB_op_setup();break;
// BPLRU算法
case 8:cache_op=BPLRU_op_setup();break;
// 自适应回写动态阈值算法
case 9:cache_op=ADCT_op_setup();break;
// 热数据识别的算法
case 10:cache_op=HotDateAware_op_setup();break;
// 添加对比的ADCT缓冲区读写对比的机制
case 11:cache_op=PURE_ADCT_op_setup();break;
}
ftl_op->init(total_util_blk_num, total_extr_blk_num);
cache_op->init(cache_size,total_util_blk_num);
nand_stat_reset();
//在这里可以申请分配对应的缓冲区的内存段
Buffer_Stat_Reset();
}
//指定运行的时间输出
void SimulationTime_Stat_Print(FILE *outFP)
{
fprintf(outFP, "\n");
fprintf(outFP, "SIMULATION TIME STATISTICS\n");
fprintf(outFP, "------------------------------------------------------------\n");
fprintf(outFP,"The I/O Simulation Time is(#) %lf\t",SimulationDelay);
fprintf(outFP,"The I/O Request Count is(#) %d\n",Req_Count);
fprintf(outFP,"The I/O Average Time is(#) %lf\t",Req_Ave_Delay);
fprintf(outFP,"The I/O Max Time is (#) %lf\n",Req_Max_Delay);
fprintf(outFP,"The I/O Min Time is (#) %lf\n",Req_Min_Delay);
fprintf(outFP, "------------------------------------------------------------\n");
}
//初始化对应的要释放内存段
void endFlash()
{
Buffer_Stat_Print(outputfile);
nand_stat_print(outputfile);
// 关于输出的运行时间跟选择的FTL和cache算法的类型都相关,因此在这插入运行时间的输出
SimulationTime_Stat_Print(outputfile);
ftl_op->end();
cache_op->end();
nand_end();
//这里也可以添加相应的缓冲区申请的内存段的释放
}
//统计相应块的磨损状况
void printWearout()
{
int i;
FILE *fp = fopen("wearout", "w");
for(i = 0; i<nand_blk_num; i++)
{
fprintf(fp, "%d %d\n", i, nand_blk[i].state.ec);
}
fclose(fp);
}
//根据相应的算法选择对应的ftl_op->write/read
/***********************************************************************
Send request (lsn, sector_cnt, operation flag)
***********************************************************************/
//这里的操作的是扇区号(tart_blk_no, block_cnt)
void send_flash_request(int start_blk_no, int block_cnt, int operation, int mapdir_flag)
{
int size;
//size_t (*op_func)(sect_t lsn, size_t size);
size_t (*op_func)(sect_t lsn, size_t size, int mapdir_flag);
if((start_blk_no + block_cnt) >= total_util_sect_num){
printf("start_blk_no: %d, block_cnt: %d, total_util_sect_num: %d\n",
start_blk_no, block_cnt, total_util_sect_num);
// exit(0);
assert(0);
}
switch(operation){
//write
case 0:
op_func = ftl_op->write;
while (block_cnt> 0) {
//回写这里也是一个扇区一个扇区的回写
size = op_func(start_blk_no, block_cnt, mapdir_flag);
start_blk_no += size;
block_cnt-=size;
}
break;
//read
case 1:
op_func = ftl_op->read;
while (block_cnt> 0) {
size = op_func(start_blk_no, block_cnt, mapdir_flag);
start_blk_no += size;
block_cnt-=size;
}
break;
default:
break;
}
}
void find_real_max()
{
int i;
for(i=0;i < MAP_REAL_MAX_ENTRIES; i++) {
if(opagemap[real_arr[i]].map_age > opagemap[real_max].map_age) {
real_max = real_arr[i];
}
}
}
void find_real_min()
{
int i,index;
int temp = 99999999;
for(i=0; i < MAP_REAL_MAX_ENTRIES; i++) {
if(opagemap[real_arr[i]].map_age <= temp) {
real_min = real_arr[i];
temp = opagemap[real_arr[i]].map_age;
index = i;
}
}
}
int find_min_ghost_entry()
{
int i;
int ghost_min = 0;
int temp = 99999999;
for(i=0; i < MAP_GHOST_MAX_ENTRIES; i++) {
if( opagemap[ghost_arr[i]].map_age <= temp) {
ghost_min = ghost_arr[i];
temp = opagemap[ghost_arr[i]].map_age;
}
}
return ghost_min;
}
void init_arr()
{
int i;
for( i = 0; i < MAP_REAL_MAX_ENTRIES; i++) {
real_arr[i] = -1;
}
for( i = 0; i < MAP_GHOST_MAX_ENTRIES; i++) {
ghost_arr[i] = -1;
}
}
int youkim_flag=0;
double callFsim(unsigned int secno, int scount, int operation)
{
double delay;
int bcount;
unsigned int blkno; // pageno for page based FTL
int cnt,z;
int min_ghost;
int pos=-1,pos_real=-1,pos_ghost=-1;
// DFTL算法初始化,初始化map_table的页数(也就是GTD)
if(ftl_type == 3) {
page_num_for_2nd_map_table = (opagemap_num / MAP_ENTRIES_PER_PAGE);
if(youkim_flag == 0 ) {
youkim_flag = 1;
init_arr();
}
if((opagemap_num % MAP_ENTRIES_PER_PAGE) != 0){
page_num_for_2nd_map_table++;
}
blkno+=page_num_for_2nd_map_table;
}
// page based FTL
if(ftl_type == 1 ) {
blkno = secno / 4;
bcount = (secno + scount -1)/4 - (secno)/4 + 1;
}
// block based FTL
else if(ftl_type == 2){
blkno = secno/4;
bcount = (secno + scount -1)/4 - (secno)/4 + 1;
}
// (DFTL)o-pagemap scheme
else if(ftl_type == 3 ) {
blkno = secno / 4;
// 访问的LPN加上翻译页的偏移量!!!,即0-page_num_for_2nd_map_table的LPN是作为翻译页的LPN保留
blkno += page_num_for_2nd_map_table;
bcount = (secno + scount -1)/4 - (secno)/4 + 1;
}
// FAST scheme
else if(ftl_type == 4){
blkno = secno/4;
bcount = (secno + scount -1)/4 - (secno)/4 + 1;
}
cnt = bcount;
reset_flash_stat();
// operation 0: write 1: read
while(cnt > 0)
{
cnt--;
// page based FTL
if(ftl_type == 1){
send_flash_request(blkno*4, 4, operation, 1);
blkno++;
}
// block based FTL
else if(ftl_type == 2){
send_flash_request(blkno*4, 4, operation, 1);
blkno++;
}
// FAST scheme
else if(ftl_type == 4){
if(operation == 0){
write_count++;
}
else read_count++;
send_flash_request(blkno*4, 4, operation, 1); //cache_min is a page for page baseed FTL
blkno++;
}
// FAST scheme end
// DFTL scheme
else if(ftl_type==3){
// 如果缓存存在对应的映射项
if((opagemap[blkno].map_status == MAP_REAL) || (opagemap[blkno].map_status == MAP_GHOST)){
opagemap[blkno].map_age++;
// 映射项在Ghost队列
if(opagemap[blkno].map_status == MAP_GHOST){
// 第一次寻找的real_min的索引初始化,从0开始,real_min可以理解为LPN(这里可能是扇区)
if ( real_min == -1 ) {
real_min = 0;
find_real_min();
}
// ghost的age大于real最小的age则会触发一次数据交换
if(opagemap[real_min].map_age <= opagemap[blkno].map_age)
{
find_real_min(); // probably the blkno is the new real_min alwaz
opagemap[blkno].map_status = MAP_REAL;
opagemap[real_min].map_status = MAP_GHOST;
pos_ghost = search_table(ghost_arr,MAP_GHOST_MAX_ENTRIES,blkno);
ghost_arr[pos_ghost] = -1;
pos_real = search_table(real_arr,MAP_REAL_MAX_ENTRIES,real_min);
real_arr[pos_real] = -1;
real_arr[pos_real] = blkno;
ghost_arr[pos_ghost] = real_min;
}
} else if(opagemap[blkno].map_status==MAP_REAL){
// 映射项在Real队列
if ( real_max == -1 ) {
real_max = 0;
find_real_max();
printf("Never happend\n");
}
if(opagemap[real_max].map_age <= opagemap[blkno].map_age)
{
real_max = blkno;
}
}else{
// 错误判断
fprintf(stderr,"forbidden/shouldnt happen real =%d , ghost =%d\n",MAP_REAL,MAP_GHOST);
assert(0);
}
// 缓存中没有对应的映射关系项
}else{
// 如果Real队列满了,则进行转移到ghost的操作
if((MAP_REAL_MAX_ENTRIES - MAP_REAL_NUM_ENTRIES) == 0){
// 如果Ghost队列满了,则进行剔除操作
if((MAP_GHOST_MAX_ENTRIES - MAP_GHOST_NUM_ENTRIES) == 0){
// 找到ghost队列中LRU的项
min_ghost = find_min_ghost_entry();
// 映射项回写剔除
if(opagemap[min_ghost].update == 1) {
update_reqd++;
opagemap[min_ghost].update = 0;
send_flash_request(((min_ghost-page_num_for_2nd_map_table)/MAP_ENTRIES_PER_PAGE)*4, 4, 1, 2); // read from 2nd mapping table then update it
send_flash_request(((min_ghost-page_num_for_2nd_map_table)/MAP_ENTRIES_PER_PAGE)*4, 4, 0, 2); // write into 2nd mapping table
}
opagemap[min_ghost].map_status = MAP_INVALID;
// 移除ghost的LRU映射项
pos = search_table(ghost_arr,MAP_GHOST_MAX_ENTRIES,min_ghost);
ghost_arr[pos]=-1;
MAP_GHOST_NUM_ENTRIES--;
}
// 将Real中的映射项移入到ghost中
MAP_REAL_NUM_ENTRIES--;
find_real_min();
opagemap[real_min].map_status = MAP_GHOST;
pos = search_table(real_arr,MAP_REAL_MAX_ENTRIES,real_min);
real_arr[pos]=-1;
pos = find_free_pos(ghost_arr,MAP_GHOST_MAX_ENTRIES);
ghost_arr[pos]=real_min;
MAP_GHOST_NUM_ENTRIES++;
}
// 将缺失的映射项载入到Real的MRU位置
send_flash_request(((blkno-page_num_for_2nd_map_table)/MAP_ENTRIES_PER_PAGE)*4, 4, 1, 2); // read from 2nd mapping table
opagemap[blkno].map_status = MAP_REAL;
opagemap[blkno].map_age = opagemap[real_max].map_age + 1;
real_max = blkno;
MAP_REAL_NUM_ENTRIES++;
pos = find_free_pos(real_arr,MAP_REAL_MAX_ENTRIES);
real_arr[pos] = blkno;
}
// 以上处理完了映射关系,下面处理数据页的更新
if(operation==0){
write_count++;
opagemap[blkno].update = 1;
}
else
read_count++;
send_flash_request(blkno*4, 4, operation, 1);
blkno++;
}
// DFTL scheme end
}
delay = calculate_delay_flash();
return delay;
}
int ZJ_flag=0;
int ShowCycle;
int ShowCount;
//上一次显示观测周期物理读写统计
int LastPhReadCount;
int LastPhWriteCount;
//上一显示观测周期的缓冲区读写命中情况
int LastReqCount;
int LastHitCount;
int LastMissCount;
int LastReqReadCount;
int LastReqWriteCount;
int LastReadHit;
int LastWriteHit;
int LastReadMiss;
int LastWirteMiss;
//上一观测周期内的缓冲区延迟情况
double ShowAveDelay;
//之后添加观测的底层写入放大系数w
//初始化观测变量的初始化函数
void InitShowVariable()
{
// 设置显示结果的周期
ShowCycle=1000;
ShowCount=0;
LastPhReadCount=0;
LastPhWriteCount=0;
LastHitCount=0;
LastMissCount=0;
LastReadHit=0;
LastReadMiss=0;
LastWirteMiss=0;
LastWriteHit=0;
ShowAveDelay=0.0;
}
//根据ShowCount判断是否显示周期观测结构
void UpdateAndShow()
{
int CurrWriteHit,CurrWriteMiss,CurrReadMiss,CurrReadHit;
int CurrReqCount,CurrReqHit,CurrReqMiss,CurrPhReadCount,CurrPhWriteCount;
double Curr_hit_rate,Read_hit_rate,Write_hit_rate;
int CurrReadCount,CurrWriteCount;
if(ShowCount==ShowCycle){
// 计算和显示
CurrReadHit=buffer_read_hit-LastReadHit;
CurrReadMiss=buffer_read_miss-LastReadMiss;
CurrWriteHit=buffer_write_hit-LastWriteHit;
CurrWriteMiss=buffer_write_miss-LastWirteMiss;
CurrReqMiss=buffer_miss_cnt-LastMissCount;
CurrReqCount=buffer_cnt-LastReqCount;
CurrReqHit=buffer_hit_cnt-LastHitCount;
CurrPhReadCount=physical_read-LastPhReadCount;
CurrPhWriteCount=physical_write-LastPhWriteCount;
Curr_hit_rate=(double)CurrReqHit/CurrReqCount;
CurrReadCount=CurrReadHit+CurrReadMiss;
CurrWriteCount=CurrWriteHit+CurrWriteMiss;
Read_hit_rate=((double)CurrReadHit)/CurrReadCount;
Write_hit_rate=((double)CurrWriteHit)/CurrWriteCount;
// 显示
// 总体命中率显示
printf("==========================CycleCount %d=====================\n",ShowCycle);
printf("Const Cycle ReqCount is %d\t hit rate is %lf\n",CurrReqCount,Curr_hit_rate);
printf("-------------------------------------------------------------\n");
// printf("Const Cycle Read Req Count is %d\t read hit rate is %lf\n",CurrReadHit+CurrReadMiss,Read_hit_rate);
printf("Const Cycle Read Req Count is %d\t Read Hit Count is %d\t Read hit rate is %lf\n",CurrReadCount,CurrReadHit,Read_hit_rate);
printf("Const Cycle Write Req Count is %d\t Write Hit Count is %d\twrite hit rate is %lf\n",CurrWriteCount,CurrWriteHit,Write_hit_rate);
printf("-------------------------------------------------------------\n");
printf("const Cycle Physical write count is %d\t Physical read count is %d\n",CurrPhWriteCount,CurrPhReadCount);
printf("*******************************************************************\n");
// 更新
LastReqCount=buffer_cnt;
LastHitCount=buffer_hit_cnt;
LastMissCount=buffer_miss_cnt;
LastReadMiss=buffer_read_miss;
LastReadHit=buffer_read_hit;
LastWirteMiss=buffer_write_miss;
LastWriteHit=buffer_write_hit;
LastPhWriteCount=physical_write;
LastPhReadCount=physical_read;
ShowCount=1;
}else{
ShowCount++;
}
}
double CacheManage(unsigned int secno,int scount,int operation)
{
double delay,flash_delay=0.0,cache_delay=0.0;
int bcount;
unsigned int blkno;
int HitIndex;
int cnt=0;
if(ZJ_flag==0){
InitShowVariable();
ZJ_flag=1;
}
//页对齐操作
blkno=secno/4;
bcount=(secno+scount-1)/4-(secno)/4+1;
//重置cache_stat相关状态
reset_cache_stat();
cnt=bcount;
while(cnt>0){
buffer_cnt++;
HitIndex=cache_op->SearchCache(blkno,operation);
if(HitIndex==-1){
// 未命中缓冲区
flash_delay+=cache_op->DelCacheEntry(blkno,operation);
flash_delay+=cache_op->AddCacheEntry(blkno,operation);
}else{
// 命中缓冲区
cache_op->HitCache(blkno,operation,HitIndex);
}
blkno++;
cnt--;
}
cache_delay=calculate_delay_cache();
delay=cache_delay+flash_delay;
// 添加周期性地输出显示
UpdateAndShow();
return delay;
}
C
1
https://gitee.com/ZhouHeyu/simulation.git
git@gitee.com:ZhouHeyu/simulation.git
ZhouHeyu
simulation
simulation
master

搜索帮助