SSDsim源码分析之Buffer_management()

Buffer_management()也就是缓存管理函数,这个是核心函数模块之一,其主要模拟数据缓存层cache的功能。

但是在SSDsim中,所谓的缓存其实主要就是一个写buffer,主要优先为写操作服务,当写请求命中时,会直接在buffer中进行一个更新;未命中时,首先根据缓存的空闲容量情况,写请求会分布成多个子请求写入缓存中。当缓存容量不足时,则先会从LRU队列中写回缓存队列中的数据,以便腾出空间提供给写请求服务。当然其中在buffer中也会有相应的读请求所需要的数据(只要读的目标数据同时也是写更新后的数据),但是当读未命中时,会直接占用channel的IO总线进入flash读数据,而且读出来的数据会直接从plane的数据寄存器中读至总线传输至host内存中,而不会再重新传输至buffer中。

这里需要简单介绍下关于SSDsim中缓存管理机制的相关知识,在SSDsim中,buffer是一个由buffer_group为单元组成的缓存层:

typedef struct buffer_group{
    TREE_NODE node;                     //树节点的结构一定要放在用户自定义结构的最前面,注意!
    struct buffer_group *LRU_link_next; // next node in LRU list
    struct buffer_group *LRU_link_pre;  // previous node in LRU list

    unsigned int group;                 //the first data logic sector number of a group stored in buffer 
    unsigned int stored;                //indicate the sector is stored in buffer or not. 1 indicates the sector is stored and 0 indicate the sector isn't stored.EX.  00110011 indicates the first, second, fifth, sixth sector is stored in buffer.
    unsigned int dirty_clean;           //it is flag of the data has been modified, one bit indicates one subpage. EX. 0001 indicates the first subpage is dirty
    int flag;                           //indicates if this node is the last 20% of the LRU list    
}buf_node;

每个buffer节点都有至多一个page页大小的数据,其中每一个buffer_group结构内又定义了一个TREENODE结构体;也就是说,通过这种嵌入TREENODE的方式,buffer中每一个节点buffer_group结构体是缓存管理单元的同时,也是一个在AVL中的一个节点。

当我们判断缓存是否命中时,就是通过将当前IO操作的缓存块对象buffer_node在初始化函数中创建的AVL树中进行遍历查找,如果该节点存在于AVL中即缓存命中;否则说明缓存未命中。这与通常的LRU缓存算法有所区别,具体原因我们会在后续博文中一一介绍。

下面我们先来详细介绍下这个buffer_management()函数的过程:

首先先贴一下源码:

struct ssd_info *buffer_management(struct ssd_info *ssd)
{   
    unsigned int j,lsn,lpn,last_lpn,first_lpn,index,complete_flag=0, state,full_page;
    unsigned int flag=0,need_distb_flag,lsn_flag,flag1=1,active_region_flag=0;           
    struct request *new_request;
    struct buffer_group *buffer_node,key;
    unsigned int mask=0,offset1=0,offset2=0;

    #ifdef DEBUG
    printf("enter buffer_management,  current time:%lld\n",ssd->current_time);
    #endif
    ssd->dram->current_time=ssd->current_time;
    full_page=~(0xffffffff<<ssd->parameter->subpage_page);

    new_request=ssd->request_tail;
    lsn=new_request->lsn;
    lpn=new_request->lsn/ssd->parameter->subpage_page;
    last_lpn=(new_request->ls
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值