您的位置:首页 > 理论基础

计算机体系结构-模拟超长字方案序列的产生与命中率的计算

2017-10-14 18:28 477 查看
#pragma region <<项目注释>>

/****************************************************************

*   作者:Stolid

*   CLR版本:**

*   创建时间:2017-10-14 下午 18:17

*   2015

*   描述说明:模拟超长字存储方案访问序列的生成,计算缓冲行的

*    访问命中率。

*

*   修改历史:

*

*

*****************************************************************/

#pragma endregion

#pragma region  头文件引入

#include<stdlib.h>

#include<stdio.h>

#include<time.h>

#pragma endregion

#pragma region 开关

#define EN_P 1   //显示每次产生用于生成指令或数据的概率

#define EN_I  1   //显示每次产生用于生成指令类型的概率

#define EN_D 1  //显示每次产生用于生成数据类型的概率

#define EN_IDX 1      //显示缓冲行指针

#define EN_delay 0   //延时处理

#pragma endregion

#pragma region 宏定义

#define sec 1000  

#pragma endregion

#pragma region 全局变量

bool flag = 1;     //首次数据访问标志

#pragma endregion

#pragma region 函数声明

void delay(long wait);

void SimMoveIdx(int M, int *idx, int L[], int *Ct, int *Hn,int TYPE);

void SimOneInstruct(int M, int *idx, float iP[],int iL[] ,int *Ct, int *Hn);

void SimOneData(int M, int *idx, float dP[], int dL[], int *Ct, int *Hn);

#pragma endregion

#pragma region  主函数

int main()

{

    srand(time(NULL));            //设置随机数种子

#pragma region 重要参数声明

    int N;                    //总模拟次数

    int M;                    //缓冲行长度

    float Pi;                //指令概率

    int  idx;                 //缓冲行指针

    int Ct = 0;            //总访问次数

    int Hn = 0;            //未命中次数

    float Pv=0;          //命中率

#pragma region 初始化指令类型或数据类型的长度与比例

    int iL[4] = { 1,2,3,4 };

    float iP[4] = { 0.4F,0.3F,0.2F,0.1F };

    int dL[4] = { 2,3,4,5 };

    float dP[4] = { 0.4F,0.3F,0.2F,0.1F };

#pragma endregion

#pragma endregion

    printf("分别输入总模拟次数、缓冲行长度、指令概率(* * *):");

    scanf("%d %d %f", &N, &M, &Pi);

    idx = int(rand() / (RAND_MAX + 1.0)*M);

#if EN_IDX

    printf("初始化idx:%d \n", idx);

#endif // EN_IDX

#pragma region 模拟进行

    for (int i = 0; i < N; i++) {

        //产生0-1的随机数

        float R = float(rand() / (RAND_MAX + 1.0));

#if EN_P

        printf("P:%.4f \n", R);

#endif // EN_P

        //模拟一条指令的访问

        if (R <= Pi)

        {

            SimOneInstruct(M, &idx, iP, iL, &Ct, &Hn);

        }

        //模拟一个数据的访问

        else

        {

            SimOneData(M, &idx, dP, dL, &Ct, &Hn);

        }

        //计算命中率

        Pv = (float)(1.0 - (float)Hn / (float)Ct);

        printf("模拟 %d 次的命中率:%.4F\n\n", i + 1, Pv);

#if EN_delay

        delay(3 * sec);

#endif // EN_delay

    }

#pragma endregion

  return 0;

}

#pragma endregion

#pragma region 模拟一条指令的产生与访问

void SimOneInstruct(int M, int *idx, float iP[], int iL[], int *Ct, int *Hn)

{

    int iTYPE;

    float R = float(rand() / (RAND_MAX + 1.0));

#if EN_P

    printf("iP:%.4f \n", R);

#endif // EN_P

    if (R <= iP[0])iTYPE = 0;

    else if (R <= iP[0] + iP[1]) iTYPE = 1;

    else if (R <= iP[0] + iP[1] + iP[2]) iTYPE = 2;

    else if (R <= 1.0) iTYPE = 3;

#if EN_I

    printf("产生第 %d 类指令,长度为%d \n", iTYPE+1,iL[iTYPE]);

#endif // EN_I

    if (iTYPE != 3) SimMoveIdx(M, idx, iL, Ct, Hn, iTYPE);

    else

    {

        *idx = int  (rand() / (RAND_MAX + 1.0)*M);

        *Ct += 1;

        *Hn += 1;

    }

#if EN_IDX

    printf("idx:%d \n", *idx);

#endif // EN_IDX

}

#pragma endregion

#pragma region 模拟一条数据的产生与访问

void SimOneData(int M, int *idx, float dP[], int dL[], int *Ct, int *Hn)

{

    int dTYPE;

    float R = float(rand() / (RAND_MAX + 1.0));

#if EN_P

    printf("dP:%.4f \n", R);

#endif // EN_P

    if (R <= dP[0]) dTYPE = 0;

    else if (R <= dP[0] + dP[1]) dTYPE = 1;

    else if (R <= dP[0] + dP[1] + dP[2]) dTYPE = 2;

    else if (R <= 1.0) dTYPE = 3;

#if EN_D

    printf("产生第 %d 类数据,长度为%d \n", dTYPE+1,dL[dTYPE]);

#endif // EN_D

    if(flag == 1)

    {

        *idx = int(rand() / (RAND_MAX + 1.0)*M);

        *Hn += 1; //未命中次数+1

        *Ct += 1;

        flag = 0; //修改标志

    }

    //模拟数据访问

    else

    {

        SimMoveIdx(M,idx,dL,Ct,Hn,dTYPE);

    }

#if EN_IDX

    printf("idx:%d \n", *idx);

#endif // EN_IDX

}

#pragma endregion

#pragma region 模拟缓冲行指针移动

void SimMoveIdx(int M, int *idx, int L[], int *Ct, int *Hn, int TYPE)

{    

    for(int i = 0; i < L[TYPE]; i++)

    {

        //模拟缓冲行指针的移动

        *idx = (int)((*idx + 1) % M);

       //跳行,即未命中

        if (*idx == 0)

        {

            *Hn += 1; //未命中数+1
        }

     *Ct += 1; //访问数+1

    }

}

#pragma endregion

#pragma region 延时函数

void delay(long wait) {

    long goal;

    goal = wait + clock();

    while (goal > clock());

}

#pragma endregion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: