adds dynamic cycle estimation

This commit is contained in:
2023-10-25 17:13:52 +02:00
parent b7478965ab
commit b86d7a517d
4 changed files with 685 additions and 53 deletions

View File

@ -1,4 +1,3 @@
/*******************************************************************************
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
@ -34,6 +33,7 @@
******************************************************************************/
#include "cycle_estimate.h"
#include <iss/plugin/calculator.h>
#include <yaml-cpp/yaml.h>
#include <iss/arch_if.h>
@ -48,11 +48,12 @@ iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
{
}
iss::plugin::cycle_estimate::~cycle_estimate() {
}
iss::plugin::cycle_estimate::~cycle_estimate() = default;
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
instr_if = vm.get_arch()->get_instrumentation_if();
assert(instr_if && "No instrumentation interface available but callback executed");
reg_base_ptr = reinterpret_cast<uint32_t*>(vm.get_arch()->get_regs_base_ptr());
if(!instr_if) return false;
const string core_name = instr_if->core_type_name();
if (config_file_name.length() > 0) {
@ -67,17 +68,23 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
auto isa_subset = p.first;
auto instructions = p.second;
for (auto const& instr : instructions) {
instr_desc res;
auto idx = instr.second["index"].as<unsigned>();
if(delays.size()<=idx)
delays.resize(idx+1);
auto& res = delays[idx];
res.is_branch = instr.second["branch"].as<bool>();
auto delay = instr.second["delay"];
if(delay.IsSequence()) {
res.not_taken = delay[0].as<uint64_t>();
res.taken = delay[1].as<uint64_t>();
} else {
res.not_taken = delay.as<uint64_t>();
res.taken = res.not_taken;
try {
res.not_taken = delay.as<uint64_t>();
res.taken = res.not_taken;
} catch (const YAML::BadConversion& e) {
res.f = iss::plugin::calculator(reg_base_ptr, delay.as<std::string>());
}
}
delays.push_back(std::move(res));
}
}
} catch (YAML::ParserException &e) {
@ -90,15 +97,18 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
}
}
return true;
}
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
assert(instr_if && "No instrumentation interface available but callback executed");
auto entry = delays[instr_info.instr_id];
bool taken = instr_if->is_branch_taken();
if (taken && (entry.taken > 1))
instr_if->update_last_instr_cycles(entry.taken);
else if (entry.not_taken > 1)
instr_if->update_last_instr_cycles(entry.not_taken);
size_t instr_id = instr_info.instr_id;
auto entry = delays[instr_id];
if(instr_info.phase_id==PRE_SYNC) {
if(entry.f)
current_delay = entry.f(instr_if->get_instr_word());
} else {
if(!entry.f)
current_delay = instr_if->is_branch_taken()? entry.taken: entry.not_taken;
if(current_delay>1)
instr_if->update_last_instr_cycles(current_delay);
}
}

View File

@ -40,24 +40,20 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
namespace iss {
namespace plugin {
class cycle_estimate: public vm_plugin {
BEGIN_BF_DECL(instr_desc, uint32_t)
BF_FIELD(taken, 24, 8)
BF_FIELD(not_taken, 16, 8)
BF_FIELD(is_branch, 8, 8)
BF_FIELD(size, 0, 8)
instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken, bool branch): instr_desc() {
this->size=size;
this->taken=taken;
this->not_taken=not_taken;
this->is_branch=branch;
}
END_BF_DECL();
struct instr_desc {
size_t size;
bool is_branch;
unsigned not_taken;
unsigned taken;
std::function<unsigned(uint64_t)> f;
};
public:
cycle_estimate() = delete;
@ -76,13 +72,15 @@ public:
bool registration(const char *const version, vm_if &arch) override;
sync_type get_sync() override { return POST_SYNC; };
sync_type get_sync() override { return ALL_SYNC; };
void callback(instr_info_t instr_info) override;
private:
iss::instrumentation_if *instr_if;
iss::instrumentation_if *instr_if{nullptr};
uint32_t* reg_base_ptr {nullptr};
std::vector<instr_desc> delays;
unsigned current_delay{0};
struct pair_hash {
size_t operator()(const std::pair<uint64_t, uint64_t> &p) const {
std::hash<uint64_t> hash;