框架模型:
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)並存放入數組中
|