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

来源:互联网 发布:程序员带什么眼镜护眼 编辑:程序博客网 时间:2024/06/07 18:19
#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


原创粉丝点击