mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-13 01:05:36 +00:00
Hadrons: better organisation of the VM
This commit is contained in:
parent
a9c8d7dad0
commit
61fc50d616
@ -94,8 +94,6 @@ void Application::run(void)
|
|||||||
}
|
}
|
||||||
vm().printContent();
|
vm().printContent();
|
||||||
env().printContent();
|
env().printContent();
|
||||||
//vm().checkGraph();
|
|
||||||
vm().memoryProfile();
|
|
||||||
if (!scheduled_)
|
if (!scheduled_)
|
||||||
{
|
{
|
||||||
schedule();
|
schedule();
|
||||||
@ -185,11 +183,11 @@ GeneticScheduler<unsigned int>::ObjFunc memPeak = \
|
|||||||
|
|
||||||
void Application::schedule(void)
|
void Application::schedule(void)
|
||||||
{
|
{
|
||||||
DEFINE_MEMPEAK;
|
//DEFINE_MEMPEAK;
|
||||||
|
|
||||||
// build module dependency graph
|
// build module dependency graph
|
||||||
LOG(Message) << "Building module graph..." << std::endl;
|
LOG(Message) << "Building module graph..." << std::endl;
|
||||||
auto graph = vm().makeModuleGraph();
|
auto graph = vm().getModuleGraph();
|
||||||
LOG(Debug) << "Module graph:" << std::endl;
|
LOG(Debug) << "Module graph:" << std::endl;
|
||||||
LOG(Debug) << graph << std::endl;
|
LOG(Debug) << graph << std::endl;
|
||||||
auto con = graph.getConnectedComponents();
|
auto con = graph.getConnectedComponents();
|
||||||
@ -276,7 +274,7 @@ void Application::saveSchedule(const std::string filename)
|
|||||||
|
|
||||||
void Application::loadSchedule(const std::string filename)
|
void Application::loadSchedule(const std::string filename)
|
||||||
{
|
{
|
||||||
DEFINE_MEMPEAK;
|
//DEFINE_MEMPEAK;
|
||||||
|
|
||||||
TextReader reader(filename);
|
TextReader reader(filename);
|
||||||
std::vector<std::string> program;
|
std::vector<std::string> program;
|
||||||
@ -290,7 +288,7 @@ void Application::loadSchedule(const std::string filename)
|
|||||||
program_.push_back(vm().getModuleAddress(name));
|
program_.push_back(vm().getModuleAddress(name));
|
||||||
}
|
}
|
||||||
scheduled_ = true;
|
scheduled_ = true;
|
||||||
memPeak_ = memPeak(program_);
|
//memPeak_ = memPeak(program_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::printSchedule(void)
|
void Application::printSchedule(void)
|
||||||
@ -323,16 +321,3 @@ void Application::configLoop(void)
|
|||||||
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
|
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
|
||||||
env().freeAll();
|
env().freeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// memory profile //////////////////////////////////////////////////////////////
|
|
||||||
void Application::memoryProfile(void)
|
|
||||||
{
|
|
||||||
auto graph = vm().makeModuleGraph();
|
|
||||||
auto program = graph.topoSort();
|
|
||||||
bool msg;
|
|
||||||
|
|
||||||
msg = HadronsLogMessage.isActive();
|
|
||||||
HadronsLogMessage.Active(false);
|
|
||||||
|
|
||||||
HadronsLogMessage.Active(msg);
|
|
||||||
}
|
|
||||||
|
@ -102,8 +102,6 @@ private:
|
|||||||
DEFINE_ENV_ALIAS;
|
DEFINE_ENV_ALIAS;
|
||||||
// virtual machine shortcut
|
// virtual machine shortcut
|
||||||
DEFINE_VM_ALIAS;
|
DEFINE_VM_ALIAS;
|
||||||
// memory profile
|
|
||||||
void memoryProfile(void);
|
|
||||||
private:
|
private:
|
||||||
long unsigned int locVol_;
|
long unsigned int locVol_;
|
||||||
std::string parameterFileName_{""};
|
std::string parameterFileName_{""};
|
||||||
|
@ -58,8 +58,5 @@ std::string ModuleBase::getRegisteredName(void)
|
|||||||
void ModuleBase::operator()(void)
|
void ModuleBase::operator()(void)
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
if (!vm().isDryRun())
|
execute();
|
||||||
{
|
|
||||||
execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -36,27 +36,6 @@ using namespace Hadrons;
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* VirtualMachine implementation *
|
* VirtualMachine implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// dry run /////////////////////////////////////////////////////////////////////
|
|
||||||
void VirtualMachine::dryRun(const bool isDry)
|
|
||||||
{
|
|
||||||
dryRun_ = isDry;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VirtualMachine::isDryRun(void) const
|
|
||||||
{
|
|
||||||
return dryRun_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::memoryProfile(const bool doMemoryProfile)
|
|
||||||
{
|
|
||||||
memoryProfile_ = doMemoryProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VirtualMachine::doMemoryProfile(void) const
|
|
||||||
{
|
|
||||||
return memoryProfile_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trajectory counter //////////////////////////////////////////////////////////
|
// trajectory counter //////////////////////////////////////////////////////////
|
||||||
void VirtualMachine::setTrajectory(const unsigned int traj)
|
void VirtualMachine::setTrajectory(const unsigned int traj)
|
||||||
{
|
{
|
||||||
@ -259,40 +238,192 @@ bool VirtualMachine::hasModule(const std::string name) const
|
|||||||
return (moduleAddress_.find(name) != moduleAddress_.end());
|
return (moduleAddress_.find(name) != moduleAddress_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph<unsigned int> VirtualMachine::makeModuleGraph(void) const
|
// print VM content ////////////////////////////////////////////////////////////
|
||||||
|
void VirtualMachine::printContent(void) const
|
||||||
{
|
{
|
||||||
Graph<unsigned int> moduleGraph;
|
LOG(Debug) << "Modules: " << std::endl;
|
||||||
|
for (unsigned int i = 0; i < module_.size(); ++i)
|
||||||
|
{
|
||||||
|
LOG(Debug) << std::setw(4) << i << ": "
|
||||||
|
<< getModuleName(i) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// module graph ////////////////////////////////////////////////////////////////
|
||||||
|
Graph<unsigned int> VirtualMachine::getModuleGraph(void)
|
||||||
|
{
|
||||||
|
if (graphOutdated_)
|
||||||
|
{
|
||||||
|
makeModuleGraph();
|
||||||
|
graphOutdated_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::makeModuleGraph(void)
|
||||||
|
{
|
||||||
|
Graph<unsigned int> graph;
|
||||||
|
|
||||||
// create vertices
|
// create vertices
|
||||||
for (unsigned int m = 0; m < module_.size(); ++m)
|
for (unsigned int m = 0; m < module_.size(); ++m)
|
||||||
{
|
{
|
||||||
moduleGraph.addVertex(m);
|
graph.addVertex(m);
|
||||||
}
|
}
|
||||||
// create edges
|
// create edges
|
||||||
for (unsigned int m = 0; m < module_.size(); ++m)
|
for (unsigned int m = 0; m < module_.size(); ++m)
|
||||||
{
|
{
|
||||||
for (auto &in: module_[m].input)
|
for (auto &in: module_[m].input)
|
||||||
{
|
{
|
||||||
moduleGraph.addEdge(env().getObjectModule(in), m);
|
graph.addEdge(env().getObjectModule(in), m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
graph_ = graph;
|
||||||
return moduleGraph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// general execution ///////////////////////////////////////////////////////////
|
// memory profile //////////////////////////////////////////////////////////////
|
||||||
#define BIG_SEP "==============="
|
const VirtualMachine::MemoryProfile & VirtualMachine::getMemoryProfile(void)
|
||||||
#define SEP "---------------"
|
|
||||||
#define MEM_MSG(size) sizeString(size)
|
|
||||||
|
|
||||||
VirtualMachine::Size
|
|
||||||
VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
|
|
||||||
{
|
{
|
||||||
Size memPeak = 0, sizeBefore, sizeAfter;
|
if (memoryProfileOutdated_)
|
||||||
std::vector<std::set<unsigned int>> freeProg;
|
{
|
||||||
|
makeMemoryProfile();
|
||||||
|
memoryProfileOutdated_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::makeMemoryProfile(void)
|
||||||
|
{
|
||||||
|
bool protect = env().objectsProtected();
|
||||||
|
bool hmsg = HadronsLogMessage.isActive();
|
||||||
|
bool gmsg = GridLogMessage.isActive();
|
||||||
|
bool err = HadronsLogError.isActive();
|
||||||
|
auto program = getModuleGraph().topoSort();
|
||||||
|
|
||||||
|
resetProfile();
|
||||||
|
profile_.module.resize(getNModule());
|
||||||
|
env().protectObjects(false);
|
||||||
|
GridLogMessage.Active(false);
|
||||||
|
HadronsLogMessage.Active(false);
|
||||||
|
HadronsLogError.Active(false);
|
||||||
|
for (auto it = program.rbegin(); it != program.rend(); ++it)
|
||||||
|
{
|
||||||
|
auto a = *it;
|
||||||
|
|
||||||
|
if (profile_.module[a].empty())
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Profiling memory for module '" << module_[a].name
|
||||||
|
<< "' (" << a << ")..." << std::endl;
|
||||||
|
memoryProfile(a);
|
||||||
|
env().freeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env().protectObjects(protect);
|
||||||
|
GridLogMessage.Active(gmsg);
|
||||||
|
HadronsLogMessage.Active(hmsg);
|
||||||
|
HadronsLogError.Active(err);
|
||||||
|
LOG(Debug) << "Memory profile:" << std::endl;
|
||||||
|
LOG(Debug) << "----------------" << std::endl;
|
||||||
|
for (unsigned int a = 0; a < profile_.module.size(); ++a)
|
||||||
|
{
|
||||||
|
LOG(Debug) << getModuleName(a) << " (" << a << ")" << std::endl;
|
||||||
|
for (auto &o: profile_.module[a])
|
||||||
|
{
|
||||||
|
LOG(Debug) << "|__ " << env().getObjectName(o.first) << " ("
|
||||||
|
<< sizeString(o.second) << ")" << std::endl;
|
||||||
|
}
|
||||||
|
LOG(Debug) << std::endl;
|
||||||
|
}
|
||||||
|
LOG(Debug) << "----------------" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::resetProfile(void)
|
||||||
|
{
|
||||||
|
profile_.module.clear();
|
||||||
|
profile_.object.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::resizeProfile(void)
|
||||||
|
{
|
||||||
|
if (env().getMaxAddress() > profile_.object.size())
|
||||||
|
{
|
||||||
|
MemoryPrint empty;
|
||||||
|
|
||||||
|
empty.size = 0;
|
||||||
|
empty.module = -1;
|
||||||
|
profile_.object.resize(env().getMaxAddress(), empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::updateProfile(const unsigned int address)
|
||||||
|
{
|
||||||
|
resizeProfile();
|
||||||
|
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
||||||
|
{
|
||||||
|
if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
|
||||||
|
{
|
||||||
|
profile_.object[a].size = env().getObjectSize(a);
|
||||||
|
profile_.object[a].module = address;
|
||||||
|
profile_.module[address][a] = profile_.object[a].size;
|
||||||
|
if (env().getObjectModule(a) < 0)
|
||||||
|
{
|
||||||
|
env().setObjectModule(a, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::cleanEnvironment(void)
|
||||||
|
{
|
||||||
|
resizeProfile();
|
||||||
|
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
||||||
|
{
|
||||||
|
if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
|
||||||
|
{
|
||||||
|
env().freeObject(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::memoryProfile(const unsigned int address)
|
||||||
|
{
|
||||||
|
auto m = getModule(address);
|
||||||
|
|
||||||
|
LOG(Debug) << "Setting up module '" << m->getName()
|
||||||
|
<< "' (" << address << ")..." << std::endl;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m->setup();
|
||||||
|
updateProfile(address);
|
||||||
|
}
|
||||||
|
catch (Exceptions::Definition &)
|
||||||
|
{
|
||||||
|
cleanEnvironment();
|
||||||
|
for (auto &in: m->getInput())
|
||||||
|
{
|
||||||
|
memoryProfile(env().getObjectModule(in));
|
||||||
|
}
|
||||||
|
for (auto &ref: m->getReference())
|
||||||
|
{
|
||||||
|
memoryProfile(env().getObjectModule(ref));
|
||||||
|
}
|
||||||
|
m->setup();
|
||||||
|
updateProfile(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::memoryProfile(const std::string name)
|
||||||
|
{
|
||||||
|
memoryProfile(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// garbage collector ///////////////////////////////////////////////////////////
|
||||||
|
VirtualMachine::GarbageSchedule
|
||||||
|
VirtualMachine::makeGarbageSchedule(const std::vector<unsigned int> &p) const
|
||||||
|
{
|
||||||
|
GarbageSchedule freeProg;
|
||||||
|
|
||||||
// build garbage collection schedule
|
|
||||||
LOG(Debug) << "Building garbage collection schedule..." << std::endl;
|
|
||||||
freeProg.resize(p.size());
|
freeProg.resize(p.size());
|
||||||
for (unsigned int i = 0; i < env().getMaxAddress(); ++i)
|
for (unsigned int i = 0; i < env().getMaxAddress(); ++i)
|
||||||
{
|
{
|
||||||
@ -310,34 +441,42 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return freeProg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// general execution ///////////////////////////////////////////////////////////
|
||||||
|
#define BIG_SEP "==============="
|
||||||
|
#define SEP "---------------"
|
||||||
|
#define MEM_MSG(size) sizeString(size)
|
||||||
|
|
||||||
|
void VirtualMachine::executeProgram(const std::vector<unsigned int> &p) const
|
||||||
|
{
|
||||||
|
Size memPeak = 0, sizeBefore, sizeAfter;
|
||||||
|
GarbageSchedule freeProg;
|
||||||
|
|
||||||
|
// build garbage collection schedule
|
||||||
|
LOG(Debug) << "Building garbage collection schedule..." << std::endl;
|
||||||
|
freeProg = makeGarbageSchedule(p);
|
||||||
|
|
||||||
// program execution
|
// program execution
|
||||||
LOG(Debug) << "Executing program..." << std::endl;
|
LOG(Debug) << "Executing program..." << std::endl;
|
||||||
for (unsigned int i = 0; i < p.size(); ++i)
|
for (unsigned int i = 0; i < p.size(); ++i)
|
||||||
{
|
{
|
||||||
// execute module
|
// execute module
|
||||||
if (!isDryRun())
|
LOG(Message) << SEP << " Measurement step " << i + 1 << "/"
|
||||||
{
|
<< p.size() << " (module '" << module_[p[i]].name
|
||||||
LOG(Message) << SEP << " Measurement step " << i+1 << "/"
|
<< "') " << SEP << std::endl;
|
||||||
<< p.size() << " (module '" << module_[p[i]].name
|
|
||||||
<< "') " << SEP << std::endl;
|
|
||||||
}
|
|
||||||
(*module_[p[i]].data)();
|
(*module_[p[i]].data)();
|
||||||
sizeBefore = env().getTotalSize();
|
sizeBefore = env().getTotalSize();
|
||||||
// print used memory after execution
|
// print used memory after execution
|
||||||
if (!isDryRun())
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
|
||||||
{
|
<< std::endl;
|
||||||
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
if (sizeBefore > memPeak)
|
if (sizeBefore > memPeak)
|
||||||
{
|
{
|
||||||
memPeak = sizeBefore;
|
memPeak = sizeBefore;
|
||||||
}
|
}
|
||||||
// garbage collection for step i
|
// garbage collection for step i
|
||||||
if (!isDryRun())
|
LOG(Message) << "Garbage collection..." << std::endl;
|
||||||
{
|
|
||||||
LOG(Message) << "Garbage collection..." << std::endl;
|
|
||||||
}
|
|
||||||
for (auto &j: freeProg[i])
|
for (auto &j: freeProg[i])
|
||||||
{
|
{
|
||||||
env().freeObject(j);
|
env().freeObject(j);
|
||||||
@ -352,25 +491,20 @@ VirtualMachine::executeProgram(const std::vector<unsigned int> &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// print used memory after garbage collection if necessary
|
// print used memory after garbage collection if necessary
|
||||||
if (!isDryRun())
|
sizeAfter = env().getTotalSize();
|
||||||
|
if (sizeBefore != sizeAfter)
|
||||||
{
|
{
|
||||||
sizeAfter = env().getTotalSize();
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
|
||||||
if (sizeBefore != sizeAfter)
|
<< std::endl;
|
||||||
{
|
}
|
||||||
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
|
else
|
||||||
<< std::endl;
|
{
|
||||||
}
|
LOG(Message) << "Nothing to free" << std::endl;
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(Message) << "Nothing to free" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return memPeak;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualMachine::Size VirtualMachine::executeProgram(const std::vector<std::string> &p)
|
void VirtualMachine::executeProgram(const std::vector<std::string> &p) const
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> pAddress;
|
std::vector<unsigned int> pAddress;
|
||||||
|
|
||||||
@ -378,138 +512,5 @@ VirtualMachine::Size VirtualMachine::executeProgram(const std::vector<std::strin
|
|||||||
{
|
{
|
||||||
pAddress.push_back(getModuleAddress(n));
|
pAddress.push_back(getModuleAddress(n));
|
||||||
}
|
}
|
||||||
|
executeProgram(pAddress);
|
||||||
return executeProgram(pAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// print VM content ////////////////////////////////////////////////////////////
|
|
||||||
void VirtualMachine::printContent(void) const
|
|
||||||
{
|
|
||||||
LOG(Debug) << "Modules: " << std::endl;
|
|
||||||
for (unsigned int i = 0; i < module_.size(); ++i)
|
|
||||||
{
|
|
||||||
LOG(Debug) << std::setw(4) << i << ": "
|
|
||||||
<< getModuleName(i) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// memory profile //////////////////////////////////////////////////////////////
|
|
||||||
VirtualMachine::MemoryProfile VirtualMachine::memoryProfile(void) const
|
|
||||||
{
|
|
||||||
bool protect = env().objectsProtected();
|
|
||||||
bool hmsg = HadronsLogMessage.isActive();
|
|
||||||
bool gmsg = GridLogMessage.isActive();
|
|
||||||
bool err = HadronsLogError.isActive();
|
|
||||||
MemoryProfile profile;
|
|
||||||
auto program = makeModuleGraph().topoSort();
|
|
||||||
|
|
||||||
profile.module.resize(getNModule());
|
|
||||||
env().protectObjects(false);
|
|
||||||
GridLogMessage.Active(false);
|
|
||||||
HadronsLogMessage.Active(false);
|
|
||||||
HadronsLogError.Active(false);
|
|
||||||
for (auto it = program.rbegin(); it != program.rend(); ++it)
|
|
||||||
{
|
|
||||||
auto a = *it;
|
|
||||||
|
|
||||||
if (profile.module[a].empty())
|
|
||||||
{
|
|
||||||
LOG(Debug) << "Profiling memory for module '" << module_[a].name
|
|
||||||
<< "' (" << a << ")..." << std::endl;
|
|
||||||
memoryProfile(profile, a);
|
|
||||||
env().freeAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env().protectObjects(protect);
|
|
||||||
GridLogMessage.Active(gmsg);
|
|
||||||
HadronsLogMessage.Active(hmsg);
|
|
||||||
HadronsLogError.Active(err);
|
|
||||||
LOG(Debug) << "Memory profile:" << std::endl;
|
|
||||||
LOG(Debug) << "----------------" << std::endl;
|
|
||||||
for (unsigned int a = 0; a < profile.module.size(); ++a)
|
|
||||||
{
|
|
||||||
LOG(Debug) << getModuleName(a) << " (" << a << ")" << std::endl;
|
|
||||||
for (auto &o: profile.module[a])
|
|
||||||
{
|
|
||||||
LOG(Debug) << "|__ " << env().getObjectName(o.first) << " ("
|
|
||||||
<< sizeString(o.second) << ")" << std::endl;
|
|
||||||
}
|
|
||||||
LOG(Debug) << std::endl;
|
|
||||||
}
|
|
||||||
LOG(Debug) << "----------------" << std::endl;
|
|
||||||
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::resizeProfile(MemoryProfile &profile) const
|
|
||||||
{
|
|
||||||
if (env().getMaxAddress() > profile.object.size())
|
|
||||||
{
|
|
||||||
MemoryPrint empty;
|
|
||||||
|
|
||||||
empty.size = 0;
|
|
||||||
empty.module = -1;
|
|
||||||
profile.object.resize(env().getMaxAddress(), empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::updateProfile(MemoryProfile &profile,
|
|
||||||
const unsigned int address) const
|
|
||||||
{
|
|
||||||
resizeProfile(profile);
|
|
||||||
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
|
||||||
{
|
|
||||||
if (env().hasCreatedObject(a) and (profile.object[a].module == -1))
|
|
||||||
{
|
|
||||||
profile.object[a].size = env().getObjectSize(a);
|
|
||||||
profile.object[a].module = address;
|
|
||||||
profile.module[address][a] = profile.object[a].size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::cleanEnvironment(MemoryProfile &profile) const
|
|
||||||
{
|
|
||||||
resizeProfile(profile);
|
|
||||||
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
|
||||||
{
|
|
||||||
if (env().hasCreatedObject(a) and (profile.object[a].module == -1))
|
|
||||||
{
|
|
||||||
env().freeObject(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::memoryProfile(MemoryProfile &profile,
|
|
||||||
const unsigned int address) const
|
|
||||||
{
|
|
||||||
auto m = getModule(address);
|
|
||||||
|
|
||||||
LOG(Debug) << "Setting up module '" << m->getName() << "' (" << address << ")..." << std::endl;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m->setup();
|
|
||||||
updateProfile(profile, address);
|
|
||||||
}
|
|
||||||
catch (Exceptions::Definition &)
|
|
||||||
{
|
|
||||||
cleanEnvironment(profile);
|
|
||||||
for (auto &in: m->getInput())
|
|
||||||
{
|
|
||||||
memoryProfile(profile, env().getObjectModule(in));
|
|
||||||
}
|
|
||||||
for (auto &ref: m->getReference())
|
|
||||||
{
|
|
||||||
memoryProfile(profile, env().getObjectModule(ref));
|
|
||||||
}
|
|
||||||
m->setup();
|
|
||||||
updateProfile(profile, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::memoryProfile(MemoryProfile &profile,
|
|
||||||
const std::string name) const
|
|
||||||
{
|
|
||||||
memoryProfile(profile, getModuleAddress(name));
|
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ class VirtualMachine
|
|||||||
{
|
{
|
||||||
SINGLETON_DEFCTOR(VirtualMachine);
|
SINGLETON_DEFCTOR(VirtualMachine);
|
||||||
public:
|
public:
|
||||||
typedef SITE_SIZE_TYPE Size;
|
typedef SITE_SIZE_TYPE Size;
|
||||||
typedef std::unique_ptr<ModuleBase> ModPt;
|
typedef std::unique_ptr<ModuleBase> ModPt;
|
||||||
|
typedef std::vector<std::set<unsigned int>> GarbageSchedule;
|
||||||
struct MemoryPrint
|
struct MemoryPrint
|
||||||
{
|
{
|
||||||
Size size;
|
Size size;
|
||||||
@ -73,11 +74,6 @@ private:
|
|||||||
size_t maxAllocated;
|
size_t maxAllocated;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
// dry run
|
|
||||||
void dryRun(const bool isDry);
|
|
||||||
bool isDryRun(void) const;
|
|
||||||
void memoryProfile(const bool doMemoryProfile);
|
|
||||||
bool doMemoryProfile(void) const;
|
|
||||||
// trajectory counter
|
// trajectory counter
|
||||||
void setTrajectory(const unsigned int traj);
|
void setTrajectory(const unsigned int traj);
|
||||||
unsigned int getTrajectory(void) const;
|
unsigned int getTrajectory(void) const;
|
||||||
@ -106,32 +102,47 @@ public:
|
|||||||
std::string getModuleNamespace(const std::string name) const;
|
std::string getModuleNamespace(const std::string name) const;
|
||||||
bool hasModule(const unsigned int address) const;
|
bool hasModule(const unsigned int address) const;
|
||||||
bool hasModule(const std::string name) const;
|
bool hasModule(const std::string name) const;
|
||||||
Graph<unsigned int> makeModuleGraph(void) const;
|
|
||||||
void checkGraph(void) const;
|
|
||||||
// print VM content
|
// print VM content
|
||||||
void printContent(void) const;
|
void printContent(void) const;
|
||||||
|
// module graph (could be a const reference if topoSort was const)
|
||||||
|
Graph<unsigned int> getModuleGraph(void);
|
||||||
// memory profile
|
// memory profile
|
||||||
MemoryProfile memoryProfile(void) const;
|
const MemoryProfile &getMemoryProfile(void);
|
||||||
|
// garbage collector
|
||||||
|
GarbageSchedule makeGarbageSchedule(const std::vector<unsigned int> &p) const;
|
||||||
|
// high-water memory function
|
||||||
|
Size memoryNeeded(const std::vector<unsigned int> &p,
|
||||||
|
const GarbageSchedule &g);
|
||||||
|
Size memoryNeeded(const std::vector<unsigned int> &p);
|
||||||
// general execution
|
// general execution
|
||||||
Size executeProgram(const std::vector<unsigned int> &p);
|
void executeProgram(const std::vector<unsigned int> &p) const;
|
||||||
Size executeProgram(const std::vector<std::string> &p);
|
void executeProgram(const std::vector<std::string> &p) const;
|
||||||
private:
|
private:
|
||||||
// environment shortcut
|
// environment shortcut
|
||||||
DEFINE_ENV_ALIAS;
|
DEFINE_ENV_ALIAS;
|
||||||
|
// module graph
|
||||||
|
void makeModuleGraph(void);
|
||||||
// memory profile
|
// memory profile
|
||||||
void resizeProfile(MemoryProfile &profile) const;
|
void makeMemoryProfile(void);
|
||||||
void updateProfile(MemoryProfile &profile, const unsigned int address) const;
|
void resetProfile(void);
|
||||||
void cleanEnvironment(MemoryProfile &profile) const;
|
void resizeProfile(void);
|
||||||
void memoryProfile(MemoryProfile &profile, const std::string name) const;
|
void updateProfile(const unsigned int address);
|
||||||
void memoryProfile(MemoryProfile &profile, const unsigned int address) const;
|
void cleanEnvironment(void);
|
||||||
|
void memoryProfile(const std::string name);
|
||||||
|
void memoryProfile(const unsigned int address);
|
||||||
private:
|
private:
|
||||||
// general
|
// general
|
||||||
bool dryRun_{false}, memoryProfile_{false};
|
|
||||||
unsigned int traj_;
|
unsigned int traj_;
|
||||||
// module and related maps
|
// module and related maps
|
||||||
std::vector<ModuleInfo> module_;
|
std::vector<ModuleInfo> module_;
|
||||||
std::map<std::string, unsigned int> moduleAddress_;
|
std::map<std::string, unsigned int> moduleAddress_;
|
||||||
std::string currentModule_{""};
|
std::string currentModule_{""};
|
||||||
|
// module graph
|
||||||
|
bool graphOutdated_{true};
|
||||||
|
Graph<unsigned int> graph_;
|
||||||
|
// memory profile
|
||||||
|
bool memoryProfileOutdated_{true};
|
||||||
|
MemoryProfile profile_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user