SSDsim源码分析之initiation

10 篇文章 1 订阅
9 篇文章 0 订阅

SSDsim之initiation

本文继续介绍SSDsim中有关的代码解析和注解:


initiation()函数的主要功能

SSDsim是一个利用仿真trace文件进行过程模拟的软件,所以对于SSDsim来说,重要的要有三个输入文件可以提供给sim进行IOtrace的信息以及相关的初始化信息,这三个文件主要分别是:

参数文件 ——>负责提供模拟的SSD的相关参数因子;
负载踪迹文件trace——>负责提供IOtrace的输入数据;
输出文件——>负责提供一个文件供SSDsim模拟完成后输出统计数据;

初始化函数initiation的功能主要是为SSD的结构体分配内存空间,其中SSD的结构体是一个极大的叠加性结构体,在这个ssd_info类型的结构体中内嵌了各个SSD闪存不同层级结构的结构体,也就是分配这个SSD结构体,同时也对每一个channel,每一个channel下的chip,每一个chip下的die,每一个die下的plane,每一个plane下的block,每一个block下的page结构体都进行了相应的初始化处理。每一个层级的结构都有对应的结构体信息,初始化过程就是利用参数文件对这些结构体进行参数的赋值。

而负责存放输入数据的参数文件也有对应的一个结构体定义parameter_value,这个结构体负责从参数文件中利用fget()函数进行参数格式数据的逐行读取和保存,参数文件说明当前实验所模拟固态盘的硬件结构,闪存转换层算法及数据缓存算法。参数文件的第一个部分包括两种类型的参数,硬件的组织结构(芯片内的晶圆数,每个晶圆中分组的数量,每个分组内的块数量等),及时间参数;第二个部分包括两种类型的参数,能耗参数和闪存转换层配置参数。

负载踪迹文件既通常所说的trace文件,用作记录特定的负载的所有的请求的到达时间,请求的类型,请求的逻辑地址,请求的大小。负载踪迹文件的所有请求都是按照时间顺序排列。SSDsim根据这个踪迹文件,可以重现出这个特定负载或者应用环境下的请求流,通过参数文件设定的硬件结构和算法,可以得到在这种负载下该硬件结构和算法的性能,从而寻找出在这个负载下最优的硬件结构和或算法。

输出文件是用来记录每个请求的响应时间,以及特定硬件结构和软件算法在服务这个负载时的性能,能耗统计结果。每个请求的队列等待时间,服务时间和响应时间都依次输出到输出文件中,在模拟完成后输出服务整个负载的平均响应时间,总能耗,读写请求数等统计信息。

initiation函数的调用关系图

首先看一下关于函数的调用关系图

initiation调用关系图

     我们从图中可以看到,这个initiation函数主要是调用了load_parameters函数进行参数文件的读取,该函数完成后则参数结构体paramenter就完成了初始化,随后进行了dram的初始化,之后就是channel的初始化,而channel的初始化随之又会初始化chip,依次反复,直到所有层级的结构都初始化完毕。最后对输出文件进行初始化,主要是将一些默认缺省的信息写入到输出文件中,而后刷新缓冲区输出到显示设备中。

initiation函数的控制流图

initiation函数的控制流图如下:

initiation控制流图

我们从控制流图可以详细直观的可以看到这个函数的过程,结合代码进行分析会有很大的便利性,
同时我们给出关于initiation函数的关系流图:

关系流图

源代码和相关注解

struct ssd_info initiation(struct ssd_info *ssd)
//初始化模拟的ssd结构所需的参数
{                                                           //SSD->channel->chip->die->plane->block->page->subpage
    unsigned int x=0,y=0,i=0,j=0,k=0,l=0,m=0,n=0;            
    //这里定义的八个uint变量应该就是指为了循环遍历初始化上述这八个层次中的所有结构参数而设定的
    errno_t err;            //errno_t类型是用于条件判断的
    char buffer[300];       //缓冲区初始化,大小为300Byte
    struct parameter_value *parameters;     //声明输入参数文件
    //指向文件指针的一个指针,FILE是C语言stdio.h头文件中定义的一个结构体类型,该结构体包含了与文件相关的一系列成员参数,如文件属性等。

    printf("input parameter file name:");
    gets(ssd->parameterfilename);


    printf("\ninput trace file name:");
    gets(ssd->tracefilename);


    printf("\ninput output file name:");
    gets(ssd->outputfilename);


    printf("\ninput statistic file name:");
    gets(ssd->statisticfilename);




    //导入ssd的配置文件
    parameters=load_parameters(ssd->parameterfilename);
    //将ssd结构体的参数导入至定义的参数文件中,而后赋值给参数结构体变量
    ssd->parameter=parameters;                          
    //直接将保存参数的结构体变量进行赋值 

    //计算ssd中每个通道channel中的的闪存页总数量
    ssd->page=ssd->parameter->chip_num*ssd->parameter->die_chip*ssd->parameter->plane_die*ssd->parameter->block_plane*ssd->parameter->page_block;

    //初始化 dram
    ssd->dram = (struct dram_info *)malloc(sizeof(struct dram_info));   //分配dram内存空间
    alloc_assert(ssd->dram,"ssd->dram");                                //判断分配情况
    memset(ssd->dram,0,sizeof(struct dram_info));                       //初始化dram的空间->清零
    /*
    初始化dram,这里会根据参数结构体中dram的相关参数对dram结构进行初始化,主要的工作是:
    dram_info结构体初始化以及设置dram容量、设置dram中的buffer缓冲区、初始化映射表
    */
    initialize_dram(ssd);                                               

    //初始化通道
    ssd->channel_head=(struct channel_info*)malloc(ssd->parameter->channel_number * sizeof(struct channel_info));
    alloc_assert(ssd->channel_head,"ssd->channel_head");    
    //分配通道并且检查内存分配情况
    //初始化清零内存
    initialize_channels(ssd);       
    //初始化通道函数,主要根据参数文件的SSD通道数对每一个通道进行初始化操作设置


    printf("\n");
    if((err=fopen_s(&ssd->outputfile,ssd->outputfilename,"w")) != 0)    //若打开输出结果文件失败则打印错误信息并且返回空指针
    {               
     //w参数即指以空文件的方式打开,相当于创建一个新文件,若存在同名文件则该同名文件内数据会被销毁
        printf("the output file can't open\n");
        return NULL;
    }

    printf("\n");
    if((err=fopen_s(&ssd->statisticfile,ssd->statisticfilename,"w"))!=0)    
    //若打开statisticfile文件失败则打印错误信息并且返回空指针
    {                       
        printf("the statistic file can't open\n");  
    //statisticfile文件是一个负责统计相关信息的文件
        return NULL;
    }

    printf("\n");


    //以下是分别按照中间的固定格式向指定文件中写入相关的文件名信息,比如第一个就是按照parameter file:***这样的格式写入文件中,其他类似
    fprintf(ssd->outputfile,"parameter file: %s\n",ssd->parameterfilename); //将参数文件名写入到outputfile中
    fprintf(ssd->outputfile,"trace file: %s\n",ssd->tracefilename); //将负载踪迹文件名写入到outputfile中
    fprintf(ssd->statisticfile,"parameter file: %s\n",ssd->parameterfilename); //将参数文件名写入到统计文件中
    fprintf(ssd->statisticfile,"trace file: %s\n",ssd->tracefilename);  //将负载踪迹文件名写入到统计文件中

    /*
     *fflush()函数:负责冲洗流中的信息,也就是清除读写缓冲区中的内容,需要立即把输出缓冲区的数据进行物理写入时;成功刷新则返回0
     *函数原型是: int fflush(FILE *stream)
     *fflush(stdin):刷新标准输入缓冲区(一般指键盘),把输入缓冲区内的东西丢弃;
     *fflush(stdout):刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上;
     *******************************************************************************************************
     *如果stream指向输出流或者更新流,并且这个更新流最近执行的操作不是输入,那么flush函数将把任何未被写入的数据写入stream指向的文件
     *否则,flush函数的行为是不确定的;fflush(NULL)清空所有输出流和更新流,如果发生写错误,flush函数会给那些流打上错误标记并且返回EOF,否则返回0
     *所以,如果stream指向输入流如stdin则fflush函数的行为是不确定的。此时使用fflush(stdin)是不正确的
     */
    fflush(ssd->outputfile);    //刷新outputfile文件中的数据并且将其打印至标准输出设备上
    fflush(ssd->statisticfile); //刷新statisticfile文件中的数据并且将其打印至标准输出设备上

    if((err=fopen_s(&fp,ssd->parameterfilename,"r"))!=0)    //以只读的方式打开参数文件,此时fp指针指向了参数文件
    {
        printf("\nthe parameter file can't open!\n");
        return NULL;
    }

    //fp=fopen(ssd->parameterfilename,"r");

    fprintf(ssd->outputfile,"-----------------------parameter file----------------------\n");
    //向outputfile文件写入格式字符串
    //同上
    while(fgets(buffer,300,fp)) 
    //这里的buffer是SSD的buffer,而并不是在初始化时使用到的buf,初始化时的buf在函数返回时便已被自动回收了
    {                           
    //逐行读取参数文件中的数据到ssd缓冲区buffer中,每次读取一行300字节后会执行循环体内的代码部分
        fprintf(ssd->outputfile,"%s",buffer);   
        //将每一行缓冲区的数据流以字符串格式写入到outputfile文件中
        fflush(ssd->outputfile);     
        //刷新outputfile文件中的数据并将其打印至标准输出设备上
        fprintf(ssd->statisticfile,"%s",buffer);     
        //将每一行缓冲区的数据流以字符串格式写入到statisfile中
        fflush(ssd->statisticfile);  
        //刷新outputfile文件中的数据并将其打印至标准输出设备上
    }   

    fprintf(ssd->outputfile,"\n");
    fprintf(ssd->outputfile,"-----------------------simulation output----------------------\n");
    fflush(ssd->outputfile);

    fprintf(ssd->statisticfile,"\n");
    fprintf(ssd->statisticfile,"-----------------------simulation output----------------------\n");
    fflush(ssd->statisticfile);

    fclose(fp); //关闭文件流
    printf("initiation is completed!\n");

    return ssd;
}
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: C SIP源码是指开发语言为C的用于实现Session Initiation Protocol (SIP)的源代码。SIP是一种用于建立、修改和终止网络会话的通信协议,主要用于语音和视频通信。 SIP协议由一系列消息组成,这些消息在终端设备之间进行交换以实现通话功能。C SIP源码提供了实现这些消息交换的函数和数据结构。 C SIP源码的核心功能包括消息解析、消息处理和会话管理。首先,源码解析接收到的SIP消息,并将其转化为可供处理的数据结构。然后,源码根据消息类型和内容执行相应的操作,例如建立会话、修改会话或终止会话。最后,源码负责管理会话状态和处理可能发生的异常情况。 对于初学者而言,理解C SIP源码可能较为困难。因此,建议先从学习C语言基础开始,了解C语言的语法和常用函数。接下来,可以研究SIP协议的工作原理和相关标准文档。一些开源的SIP实现,如PJ ### 回答2: C SIP源码是一个用C语言编写的简单的SIP协议的实现。SIP(Session Initiation Protocol)是一种用于建立、修改和终止多媒体会话的通信协议。通过使用SIP,用户可以进行语音通话、视频通话和实时消息传输等多媒体通信。 C SIP源码的主要功能包括与SIP服务器的连接建立、实现SIP会话的建立和管理、SIP消息的解析和封装以及与媒体服务器的接口等。源码中涉及的核心概念和模块包括SIP请求和应答的封装和解析、SIP消息的路由和转发、SIP会话的状态管理和会话描述信息的维护。 在C SIP源码中,使用了一些基本的数据结构和算法,例如链表和哈希表。通过这些数据结构和算法,源码能够实现对SIP消息和会话的高效管理和处理。 对于开发人员来说,理解和使用C SIP源码需要对SIP协议有一定的了解,并具备C语言编程的基本能力。开发人员可以通过阅读源码来学习SIP协议的具体实现方式、学习如何对SIP消息进行解析和封装以及了解SIP会话的状态管理方法等。在实际开发中,开发人员可以根据自己的需求和业务场景对源码进行定制和扩展,以实现特定的功能和业务逻辑。 总之,C SIP源码是一个简单的SIP协议实现,通过阅读和理解源码,开发人员可以学习和掌握SIP协议的具体实现方式,并能够根据需求进行自定义开发。 ### 回答3: C SIP源码是用C语言编写的一个简单的SIP(Session Initiation Protocol)实现的代码库。SIP是一种用于建立、修改和终止多媒体会话的应用层协议,常用于VoIP(Voice over Internet Protocol)和实时通信应用。 这个简单的C SIP源码提供了一些基本的功能来实现SIP通信。它可能包含了处理SIP消息的函数、建立SIP会话的代码和处理SIP响应的逻辑等。 在源码中,可能会定义一些用于处理SIP请求和响应的结构和数据类型,例如SIP消息、SIP头部和SIP URI(Uniform Resource Identifier)等。 此外,源码中可能还包含了用于网络通信的函数和数据结构,以及实现SIP状态机和会话管理的代码。 这个简单的C SIP源码可能只包含了基本的SIP功能,如用户注册、呼叫建立和呼叫终止等。如果需要更复杂的功能,如安全认证、传输层协议选择和媒体处理等,可能需要在基础上进一步扩展和修改。 总而言之,简单的C SIP源码是一个提供基本的SIP功能的代码库,可以用来学习和理解SIP协议的实现原理,以及构建简单的SIP应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值