#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
}
#pragma endregion
#pragma region 延时函数
void delay(long wait) {
long goal;
goal = wait + clock();
while (goal > clock());
}
#pragma endregion
/****************************************************************
* 作者: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