rework cycle estimation

This commit is contained in:
2022-02-01 19:03:45 +01:00
parent ef2a4df925
commit 059bd0d371
4 changed files with 161 additions and 131 deletions

View File

@@ -36,57 +36,76 @@
#include <iss/arch_if.h>
#include <util/logging.h>
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <rapidjson/ostreamwrapper.h>
#include <fstream>
iss::plugin::cycle_estimate::cycle_estimate(std::string config_file_name)
using namespace rapidjson;
using namespace std;
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
: arch_instr(nullptr)
, config_file_name(config_file_name)
{
if (config_file_name.length() > 0) {
std::ifstream is(config_file_name);
if (is.is_open()) {
try {
is >> root;
} catch (Json::RuntimeError &e) {
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
}
} else {
LOG(ERR) << "Could not open input file " << config_file_name;
}
}
}
iss::plugin::cycle_estimate::~cycle_estimate() {
}
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
arch_instr = vm.get_arch()->get_instrumentation_if();
if(!arch_instr) return false;
const std::string core_name = arch_instr->core_type_name();
Json::Value &val = root[core_name];
if(!val.isNull() && val.isArray()){
delays.reserve(val.size());
for(auto it:val){
auto name = it["name"];
auto size = it["size"];
auto delay = it["delay"];
if(!name.isString() || !size.isUInt() || !(delay.isUInt() || delay.isArray())) throw std::runtime_error("JSON parse error");
if(delay.isUInt()){
delays.push_back(instr_desc{size.asUInt(), delay.asUInt(), 0});
} else {
delays.push_back(instr_desc{size.asUInt(), delay[0].asUInt(), delay[1].asUInt()});
}
}
} else {
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
arch_instr = vm.get_arch()->get_instrumentation_if();
if(!arch_instr) return false;
const string core_name = arch_instr->core_type_name();
if (config_file_name.length() > 0) {
ifstream is(config_file_name);
if (is.is_open()) {
try {
IStreamWrapper isw(is);
Document d;
ParseResult ok = d.ParseStream(isw);
if(ok) {
Value& val = d[core_name];
if(val.IsArray()){
delays.reserve(val.Size());
for(auto it:val.GetArray()){
auto name = it["name"];
auto size = it["size"];
auto delay = it["delay"];
if(delay.IsArray()) {
delays.push_back(instr_desc{size.Get<unsigned>(), delay[0].Get<unsigned>(), delay[1].Get<unsigned>()});
} else if(delay.Is<unsigned>()) {
delays.push_back(instr_desc{size.Get<unsigned>(), delay.Get<unsigned>(), 0});
} else
throw runtime_error("JSON parse error");
}
} else {
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl;
return false;
}
} else {
LOG(ERR)<<"plugin cycle_estimate: could not parse in JSON file"<<endl;
return false;
}
} catch (runtime_error &e) {
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
return false;
}
} else {
LOG(ERR) << "Could not open input file " << config_file_name;
return false;
}
}
return true;
return true;
}
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const&) {
assert(arch_instr && "No instrumentation interface available but callback executed");
auto entry = delays[instr_info.instr_id];
bool taken = (arch_instr->get_next_pc()-arch_instr->get_pc()) != (entry.size/8);
auto entry = delays[instr_info.instr_id];
bool taken = (arch_instr->get_next_pc()-arch_instr->get_pc()) != (entry.size/8);
if (taken && entry.taken > 1)
arch_instr->set_curr_instr_cycles(entry.taken);
else if (entry.not_taken > 1)