1 Star 0 Fork 0

Admin/cacti

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
memcad.cc 16.24 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
#include "memcad.h"
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cassert>
using namespace std;
vector<channel_conf*> *memcad_all_channels;
vector<bob_conf*> *memcad_all_bobs;
vector<memory_conf*> *memcad_all_memories;
vector<memory_conf*> *memcad_best_results;
bool compare_channels(channel_conf* first, channel_conf* second)
{
if(first->capacity != second->capacity)
return (first->capacity < second->capacity);
MemCad_metrics first_metric = first->memcad_params->first_metric;
MemCad_metrics second_metric = first->memcad_params->second_metric;
MemCad_metrics third_metric = first->memcad_params->third_metric;
switch(first_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(second_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(third_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
return true;
}
void prune_channels()
{
vector<channel_conf*> * temp = new vector<channel_conf*>();
int last_added = -1;
for(unsigned int i=0;i< memcad_all_channels->size();i++)
{
if(last_added != (*memcad_all_channels)[i]->capacity)
{
temp->push_back(clone((*memcad_all_channels)[i]));
last_added = (*memcad_all_channels)[i]->capacity;
}
}
for(unsigned int i=0;i< memcad_all_channels->size();i++)
{
delete (*memcad_all_channels)[i];
}
memcad_all_channels->clear();
delete memcad_all_channels;
memcad_all_channels = temp;
}
void find_all_channels(MemCadParameters * memcad_params)
{
int DIMM_size[]={0,4,8,16,32,64};
Mem_IO_type current_io_type = memcad_params->io_type;
DIMM_Model current_dimm_model = memcad_params->dimm_model;
memcad_all_channels= new vector<channel_conf*>();
// channels can have up to 3 DIMMs per channel
// di is the capacity if i-th dimm in the channel
for(int d1=0; d1<6;d1++)
{
for(int d2=d1;d2<6;d2++)
{
for(int d3=d2;d3<6;d3++)
{
// channel capacity should not exceed the entire memory capacity.
if((DIMM_size[d1]+DIMM_size[d2]+DIMM_size[d3])>memcad_params->capacity)
continue;
if( ((current_dimm_model== JUST_LRDIMM) || (current_dimm_model== ALL))
&& ((d1==0) || (MemoryParameters::cost[current_io_type][2][d1-1]<INF))
&& ((d2==0) || (MemoryParameters::cost[current_io_type][2][d2-1]<INF))
&& ((d3==0) || (MemoryParameters::cost[current_io_type][2][d3-1]<INF)) )
{
int num_dimm_per_channel =0;
vector<int> dimm_cap;
dimm_cap.push_back(DIMM_size[d1]); if(d1>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d2]); if(d2>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d3]); if(d3>0) num_dimm_per_channel++;
int max_index = bw_index(current_io_type, MemoryParameters::bandwidth_load[current_io_type][4-num_dimm_per_channel]);
for(int bw_id=0;bw_id<=max_index; ++bw_id)
{
int bandwidth = MemoryParameters::bandwidth_load[current_io_type][bw_id];
channel_conf * new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, LRDIMM, false);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
if((DIMM_size[d1]+DIMM_size[d2]+DIMM_size[d3])==0)
continue;
if(memcad_params->low_power_permitted)
{
new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, LRDIMM, true);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
}
}
}
if( (current_dimm_model== JUST_RDIMM) || (current_dimm_model== ALL)
&& ((d1==0) || (MemoryParameters::cost[current_io_type][1][d1-1]<INF))
&& ((d2==0) || (MemoryParameters::cost[current_io_type][1][d2-1]<INF))
&& ((d3==0) || (MemoryParameters::cost[current_io_type][1][d3-1]<INF)) )
{
int num_dimm_per_channel =0;
vector<int> dimm_cap;
dimm_cap.push_back(DIMM_size[d1]); if(d1>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d2]); if(d2>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d3]); if(d3>0) num_dimm_per_channel++;
if((DIMM_size[d1]+DIMM_size[d2]+DIMM_size[d3])==0)
continue;
int max_index = bw_index(current_io_type, MemoryParameters::bandwidth_load[current_io_type][4-num_dimm_per_channel]);
for(int bw_id=0;bw_id<=max_index; ++bw_id)
{
int bandwidth = MemoryParameters::bandwidth_load[current_io_type][bw_id];
channel_conf * new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, RDIMM, false);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
if(memcad_params->low_power_permitted)
{
new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, RDIMM, true);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
}
}
}
if( (current_dimm_model== JUST_UDIMM) || (current_dimm_model== ALL)
&& ((d1==0) || (MemoryParameters::cost[current_io_type][0][d1-1]<INF))
&& ((d2==0) || (MemoryParameters::cost[current_io_type][0][d2-1]<INF))
&& ((d3==0) || (MemoryParameters::cost[current_io_type][0][d3-1]<INF)) )
{
int num_dimm_per_channel =0;
vector<int> dimm_cap;
dimm_cap.push_back(DIMM_size[d1]); if(d1>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d2]); if(d2>0) num_dimm_per_channel++;
dimm_cap.push_back(DIMM_size[d3]); if(d3>0) num_dimm_per_channel++;
if((DIMM_size[d1]+DIMM_size[d2]+DIMM_size[d3])==0)
continue;
int max_index = bw_index(current_io_type, MemoryParameters::bandwidth_load[current_io_type][4-num_dimm_per_channel]);
for(int bw_id=0;bw_id<=max_index; ++bw_id)
{
int bandwidth = MemoryParameters::bandwidth_load[current_io_type][bw_id];
channel_conf * new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, UDIMM, false);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
if(memcad_params->low_power_permitted)
{
new_channel = new channel_conf(memcad_params, dimm_cap, bandwidth, UDIMM, true);
if(new_channel->cost <INF)
{
memcad_all_channels->push_back(new_channel);
}
}
}
}
}
}
}
sort(memcad_all_channels->begin(), memcad_all_channels->end(), compare_channels);
prune_channels();
if(memcad_params->verbose)
{
for(unsigned int i=0;i<memcad_all_channels->size();i++)
{
cout << *(*memcad_all_channels)[i] << endl;
}
}
}
bool compare_channels_bw(channel_conf* first, channel_conf* second)
{
return (first->bandwidth < second->bandwidth);
}
bool compare_bobs(bob_conf* first, bob_conf* second)
{
if(first->capacity != second->capacity)
return (first->capacity < second->capacity);
MemCad_metrics first_metric = first->memcad_params->first_metric;
MemCad_metrics second_metric = first->memcad_params->second_metric;
MemCad_metrics third_metric = first->memcad_params->third_metric;
switch(first_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(second_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(third_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
return true;
}
void prune_bobs()
{
vector<bob_conf*> * temp = new vector<bob_conf*>();
int last_added = -1;
for(unsigned int i=0;i< memcad_all_bobs->size();i++)
{
if(last_added != (*memcad_all_bobs)[i]->capacity)
{
temp->push_back(clone((*memcad_all_bobs)[i]));
last_added = (*memcad_all_bobs)[i]->capacity;
}
}
for(unsigned int i=0;i< memcad_all_bobs->size();i++)
{
delete (*memcad_all_bobs)[i];
}
memcad_all_bobs->clear();
delete memcad_all_bobs;
memcad_all_bobs = temp;
}
void find_bobs_recursive(MemCadParameters * memcad_params,int start,int end,int nb, list<int> *channel_index)
{
if(nb==1)
{
for(int i=start; i<=end;++i)
{
channel_index->push_back(i);
vector<channel_conf*> temp;
for(list<int>::iterator it= channel_index->begin(); it!= channel_index->end(); it++)
{
int idx = *it;
temp.push_back((*memcad_all_channels)[idx]);
}
memcad_all_bobs->push_back(new bob_conf(memcad_params, &temp));
temp.clear();
channel_index->pop_back();
}
return;
}
for(int i=start;i<=end;++i)
{
channel_index->push_back(i);
find_bobs_recursive(memcad_params,i,end,nb-1,channel_index);
channel_index->pop_back();
}
}
void find_all_bobs(MemCadParameters * memcad_params)
{
memcad_all_bobs = new vector<bob_conf*>();
if(memcad_params->mirror_in_bob)
{
for(unsigned int i=0;i<memcad_all_channels->size();++i)
{
vector<channel_conf*> channels;
for(int j=0;j<memcad_params->num_channels_per_bob;j++)
channels.push_back((*memcad_all_channels)[i]);
memcad_all_bobs->push_back(new bob_conf(memcad_params, &channels));
channels.clear();
}
}
else if(memcad_params->same_bw_in_bob)
{
sort(memcad_all_channels->begin(), memcad_all_channels->end(), compare_channels_bw);
vector<int> start_index; start_index.push_back(0);
vector<int> end_index;
int last_bw =(*memcad_all_channels)[0]->bandwidth;
for(unsigned int i=0;i< memcad_all_channels->size();i++)
{
if(last_bw!=(*memcad_all_channels)[i]->bandwidth)
{
end_index.push_back(i-1);
start_index.push_back(i);
last_bw = (*memcad_all_channels)[i]->bandwidth;
}
}
end_index.push_back(memcad_all_channels->size()-1);
list<int> channel_index;
for(unsigned int i=0;i< start_index.size();++i)
{
find_bobs_recursive(memcad_params,start_index[i],end_index[i],memcad_params->num_channels_per_bob, &channel_index);
}
}
else
{
cout << "We do not support different frequencies per in a BoB!" << endl;
assert(false);
}
sort(memcad_all_bobs->begin(), memcad_all_bobs->end(), compare_bobs);
prune_bobs();
if(memcad_params->verbose)
{
for(unsigned int i=0;i<memcad_all_bobs->size();i++)
{
cout << *(*memcad_all_bobs)[i] << endl;
}
}
}
void find_mems_recursive(MemCadParameters * memcad_params, int remaining_capacity, int start, int nb, list<int>* bobs_index)
{
if(nb==1)
{
for(unsigned int i=start; i< memcad_all_bobs->size();++i)
{
if((*memcad_all_bobs)[i]->capacity != remaining_capacity)
continue;
bobs_index->push_back(i);
vector<bob_conf*> temp;
for(list<int>::iterator it= bobs_index->begin(); it!= bobs_index->end(); it++)
{
int index = *it;
temp.push_back((*memcad_all_bobs)[index]);
}
memcad_all_memories->push_back(new memory_conf(memcad_params, &temp));
temp.clear();
bobs_index->pop_back();
}
return;
}
for(unsigned int i=start; i<memcad_all_bobs->size();i++)
{
if((*memcad_all_bobs)[i]->capacity > remaining_capacity)
continue;
int new_remaining_capacity = remaining_capacity-(*memcad_all_bobs)[i]->capacity;
bobs_index->push_back(i);
find_mems_recursive(memcad_params, new_remaining_capacity, i, nb-1, bobs_index);
bobs_index->pop_back();
}
}
//void find_mems_recursive(MemCadParameters * memcad_params, int start, int
bool compare_memories(memory_conf* first, memory_conf* second)
{
if(first->capacity != second->capacity)
return (first->capacity < second->capacity);
MemCad_metrics first_metric = first->memcad_params->first_metric;
MemCad_metrics second_metric = first->memcad_params->second_metric;
MemCad_metrics third_metric = first->memcad_params->third_metric;
switch(first_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(second_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
switch(third_metric)
{
case(Cost):
if(first->cost != second->cost)
return (first->cost < second->cost);
break;
case(Bandwidth):
if(first->bandwidth != second->bandwidth)
return (first->bandwidth > second->bandwidth);
break;
case(Energy):
if( fabs(first->energy_per_access - second->energy_per_access)>EPS)
return (first->energy_per_access < second->energy_per_access);
break;
default:
assert(false);
}
return true;
}
bool find_all_memories(MemCadParameters * memcad_params)
{
memcad_all_memories = new vector<memory_conf*>();
list<int> bobs_index;
find_mems_recursive(memcad_params, memcad_params->capacity, 0,memcad_params->num_bobs, &bobs_index);
sort(memcad_all_memories->begin(), memcad_all_memories->end(), compare_memories);
if(memcad_params->verbose)
{
cout << "all possible results:" << endl;
for(unsigned int i=0;i<memcad_all_memories->size();i++)
{
cout << *(*memcad_all_memories)[i] << endl;
}
}
if(memcad_all_memories->size()==0)
{
cout << "No result found " << endl;
return false;
}
cout << "top 3 best memory configurations are:" << endl;
int min_num_results = (memcad_all_memories->size()>3?3:memcad_all_memories->size());
for(int i=0;i<min_num_results;++i)
{
if((*memcad_all_memories)[i])
cout << *(*memcad_all_memories)[i] << endl;
}
return true;
}
void clean_results()
{
for(unsigned int i=0;i<memcad_all_channels->size();++i)
{
delete (*memcad_all_channels)[i];
}
delete memcad_all_channels;
for(unsigned int i=0;i<memcad_all_bobs->size();++i)
{
delete (*memcad_all_bobs)[i];
}
delete memcad_all_bobs;
for(unsigned int i=0;i<memcad_all_memories->size();++i)
{
delete (*memcad_all_memories)[i];
}
delete memcad_all_memories;
}
void solve_memcad(MemCadParameters * memcad_params)
{
find_all_channels(memcad_params);
find_all_bobs(memcad_params);
find_all_memories(memcad_params);
clean_results();
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/huel_zsf/cacti.git
git@gitee.com:huel_zsf/cacti.git
huel_zsf
cacti
cacti
master

搜索帮助