框架模型:
clients------------proxy cache ----------------server
仿真程序:(全部代码)版权所有
//流媒体代理缓存仿真程序
//Eddy.2007.10.12
//环境:vc++6.0
//程序说明采用先程序后描述的形式。
//包含的头文件
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<windows.h>
#include<iostream.h>
//宏定义
#define block_num 300
#define request_num 3000
#define cache_size 400
#define mozart 110
int main()
{
int hit_on;
int hit_miss;
int a[block_num]={0}; //各块的访问次数,测试用
int request[request_num]; //请求的块序号
int block_fre[block_num]; //各块的访问频率
int block_cached[mozart]; //被缓存的块,前110块的长度为400,所以最多缓存110块
double sever_stream;
double cache_stream;
double sever_load;
double hit_rate;
double freecache_size;
double block_size[block_num]; //各块的长度
double block_value[block_num];//各块的价值量
double dvalue[request_num]; //产生的0到1之间的随机数
double AverageRandom(double min,double max);
block_size[-1]=0.0; //初始缓存中-1块的长度为0
block_size[0]=1.0; //第一块长度为1
for (int l=1;l<block_num;l++)
block_size[l]=pow(1.02,l)*1;
//以1.02为比例常数,依次增加块长度,所有块总长18961.7,前200块总长2574.24
for (int n=1;block_size[0]<800;n++)
block_size[0]=block_size[0]+block_size[n];
//产生的随机访问基本集中在前200块,所以定内存长度为400
//cout<<n; //统计前110块的总长
srand(GetTickCount());
//srand(34);
for (int i=0;i<(request_num/1000);i++)
//产生request_num个0到block_num之间的服从指数分布的随机数
for(int j=(0+i*1000);j<(1000+i*1000);j++)
{
dvalue[j]=-(log(1-AverageRandom(0,1)/log(8)));
/ /产生1000个0到1之间的服从指数分布的随机数
request[j]=int((dvalue[j]*block_num)); //转化为0到block_num之间的服从指数分布的随机整数
//cout<<request[j]<<" ";
//a[request[j]]=a[request[j]]+1;//统计各块的访问次数
}
/ /for(int k=0;k<block_num;k++) //输出各块的访问次数
//cout<<a[k]<<" ";
for(int z=0;z<4;z++)
{
sever_stream=0.0;
cache_stream=0.0;
hit_on=0;
hit_miss=0;
hit_rate=0.0;
freecache_size=cache_size;
for (int y=0;y<block_num;y++) //初始化各块访问频率和价值量
{
block_fre[y]=0;
block_value[y]=0;
}
for (int m=0;m<mozart;m++)
block_cached[m]=-1;
int temp=0;
for(int p=0;p<request_num;p++)
{
int nofinding=0;
if(z==0)
{
block_fre[request[p]]++;
block_value[request[p]]=pow(block_fre[request[p]],2)/block_size[request[p]];
}
else if(z==1)
{
block_fre[request[p]]++;
block_value[request[p]]=block_fre[request[p]];
}
else if(z==2)
block_value[request[p]]=temp++;
else if(z==3)
block_value[request[p]]=1/block_size[request[p]];
else;
block_value[-1]=-1; //初始缓存中-1块的价值都是-1
for(int q=0;q<mozart;q++)
{
if (request[p]==block_cached[q])
{
hit_on++;
cache_stream=cache_stream+block_size[request[p]];
for(int r=q+1;(block_value[request[p]]>block_value[block_cached[r]]) &&r<mozart;r++);
// 访问块的价值量改变后
for(int s=q;s<r-1;s++)block_cached[s]=block_cached[s+1];
// 重新对缓存堆栈排序
block_cached[r-1]=request[p];
break;
}
else nofinding++;
}
if (nofinding==mozart)
{
hit_miss++;
sever_stream=sever_stream+block_size[request[p]];
if (freecache_size>=block_size[request[p]])
//空闲缓存比块大时
{
freecache_size=freecache_size-block_size[request[p]];
//刷新空闲缓存的大小
for(int t=0;(block_value[request[p]]>block_value[block_cached[t]]&&t<mozart;t++);
//将块存入缓存并根据价值
for(int u=0;u<t-1;u++)block_cached[u]=block_cached[u+1];
//量重新排序
block_cached[t-1]=request[p];
}
else //空闲缓存不足时
{
double add_size1=0;
for(int v=0;(block_value[request[p]]>block_value[block_cached[v]])&&v<mozart;++v)
//统计价值量比请求块小的块的总长
add_size1=add_size1+block_size[block_cached[v]];
if (add_size1<block_size[request[p]]);
//不发生替换
else
{
double add_size2=0;
for(int w=0;block_size[request[p]]>add_size2;w++)
//统计需要替换的块数
add_size2=add_size2+block_size[block_cached[w]];
for(int x=0;x<w-1;x++)
//进行替换
block_cached[x]=-1;
block_cached[w-1]=request[p];
freecache_size=freecache_size-block_size[request[p]]+add_size2;
//刷新空闲缓存的大小
}
}
}
}
hit_rate=double(hit_on)/double(hit_on+hit_miss);
sever_load=sever_stream/(sever_stream+cache_stream);
if(z==0)
{
cout<<"The hit rate of the proposed algorithm is "<<hit_rate<<endl;
cout<<"The sever load of the proposed algorithm is"<<sever_load<<endl;
cout<<"The average delay time of the proposed algorithm is "<<(double (hit_on*1+hit_miss*10)/double(request_num))<<"ms"<<endl<<endl;
}
else if(z==1)
{
cout<<"The hit rate of the LFU algorithm is "<<hit_rate<<endl;
cout<<"The sever load of the LFU algorithm is"<<sever_load<<endl;
cout<<"The average delay time of the LFU algorithm is "<<(double(hit_on*1+hit_miss*10)/double(request_num))<<"ms"<<endl<<endl;
}
else if(z==2)
{
cout<<"The hit rate of the LRU algorithm is "<<hit_rate<<endl;
cout<<"The sever load of the LRU algorithm is"<<sever_load<<endl;
cout<<"The average delay time of the LRU algorithm is "<<(double(hit_on*1+hit_miss*10)/double(request_num))<<"ms"<<endl<<endl;
}
else if(z==3)
{
cout<<"The hit rate of the SIZE algorithm is "<<hit_rate<<endl;
cout<<"The sever load of the SIZE algorithm is"<<sever_load<<endl;
cout<<"The average delay time of the SIZE algorithm is "<<(double(hit_on*1+hit_miss*10)/double(request_num))<<"ms"<<endl<<endl;
}
else;
}
return 0;
}
double AverageRandom(double min,double max)
//产生min到max之间的服从均匀分布的随机数
{
int minInteger = (int)(min*10000);
int maxInteger = (int)(max*10000);
int randInteger = rand()*rand();
int diffInteger = maxInteger - minInteger;
int resultInteger = randInteger % diffInteger + minInteger;
return resultInteger/10000.0;
}
未击中次数++ 源服务器流量自加该请求块大小。 执行图4-3的流程。 i++ |
击中次数++ 代理服务器流量自加该请求块大小。 对缓存重新排序。 i++ |
i=n |
计算输出击中率,平均延时和服务器负载率 z++ |
z=0 |
z=2 |
z=1 |
是 |
否 |
请求i(初始化为0) |
请求块是否存在 |
搜索缓存 |
更新对应块的f
|
更新对应块的f
|
更新对应块的f
|
初始化各参量,缓存数组,分块大小数组,块访问频率与块价值数组。 |
产生随机访问请求i(0,1,2,……n)并存放入数组中
|