aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-05-23 20:23:10 +0200
committerKarel Kočí <cynerd@email.cz>2018-05-23 20:23:10 +0200
commitddde26b916c99078421992100849101455756415 (patch)
tree25a8dee1fb6ae3a78d5a46e2aabd5aa4f8bb7fb3 /qtmips_machine
parentf1fc0fc1ad628d19382fe2a026a767af6f6ba12f (diff)
downloadqtmips-ddde26b916c99078421992100849101455756415.tar.gz
qtmips-ddde26b916c99078421992100849101455756415.tar.bz2
qtmips-ddde26b916c99078421992100849101455756415.zip
Add cache statistics
Diffstat (limited to 'qtmips_machine')
-rw-r--r--qtmips_machine/cache.cpp65
-rw-r--r--qtmips_machine/cache.h10
-rw-r--r--qtmips_machine/machineconfig.cpp4
-rw-r--r--qtmips_machine/qtmipsmachine.cpp4
4 files changed, 64 insertions, 19 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp
index 753027a..acc48b1 100644
--- a/qtmips_machine/cache.cpp
+++ b/qtmips_machine/cache.cpp
@@ -2,11 +2,15 @@
using namespace machine;
-Cache::Cache(Memory *m, const MachineConfigCache *cc) : cnf(cc) {
+Cache::Cache(Memory *m, const MachineConfigCache *cc, unsigned memory_access_penalty_r, unsigned memory_access_penalty_w) : cnf(cc) {
mem = m;
+ access_pen_r = memory_access_penalty_r;
+ access_pen_w = memory_access_penalty_w;
// Zero hit and miss rate
- hitc = 0;
- missc = 0;
+ hit_read = 0;
+ hit_write = 0;
+ miss_read = 0;
+ miss_write = 0;
// Skip any other initialization if cache is disabled
if (!cc->enabled())
return;
@@ -73,11 +77,31 @@ void Cache::sync() {
}
unsigned Cache::hit() const {
- return hitc;
+ return hit_read + hit_write;
}
unsigned Cache::miss() const {
- return missc;
+ return miss_read + miss_write;
+}
+
+unsigned Cache::stalled_cycles() const {
+ return miss_read * (access_pen_r - 1) + miss_write * (access_pen_w - 1);
+}
+
+double Cache::speed_improvement() const {
+ unsigned comp = hit_read + hit_write + miss_read + miss_write;
+ if (comp == 0)
+ return 100.0;
+ return (double)((miss_read + hit_read) * access_pen_r + (miss_write + hit_write) * access_pen_w) \
+ / (double)(hit_write + hit_read + miss_read * access_pen_r + miss_write * access_pen_w) \
+ * 100;
+}
+
+double Cache::usage_efficiency() const {
+ unsigned comp = hit_read + hit_write + miss_read + miss_write;
+ if (comp == 0)
+ return 0.0;
+ return (double)(hit_read + hit_write) / (double)comp * 100.0;
}
void Cache::reset() {
@@ -90,11 +114,14 @@ void Cache::reset() {
dt[as][st].valid = false;
// Note: we don't have to zero replacement policy data as those are zeroed when first used on invalid cell
// Zero hit and miss rate
- hitc = 0;
- missc = 0;
+ hit_read = 0;
+ hit_write = 0;
+ miss_read = 0;
+ miss_write = 0;
// Trigger signals
- emit hit_update(hitc);
- emit miss_update(missc);
+ emit hit_update(hit());
+ emit miss_update(miss());
+ update_statistics();
for (unsigned as = 0; as < cnf.associativity(); as++)
for (unsigned st = 0; st < cnf.sets(); st++)
emit cache_update(as, st, false, false, 0, 0);
@@ -157,11 +184,19 @@ void Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
// Update statistics and otherwise read from memory
if (cd.valid) {
- hitc++;
- emit hit_update(hitc);
+ if (write)
+ hit_write++;
+ else
+ hit_read++;
+ emit hit_update(hit());
+ update_statistics();
} else {
- missc++;
- emit miss_update(missc);
+ if (write)
+ miss_write++;
+ else
+ miss_read++;
+ emit miss_update(miss());
+ update_statistics();
for (unsigned i = 0; i < cnf.blocks(); i++)
cd.data[i] = mem->rword(base_address(tag, row) + (4*i));
}
@@ -209,3 +244,7 @@ void Cache::kick(unsigned associat_indx, unsigned row) const {
std::uint32_t Cache::base_address(std::uint32_t tag, unsigned row) const {
return ((tag * cnf.blocks() * cnf.sets()) + (row * cnf.blocks())) << 2;
}
+
+void Cache::update_statistics() const {
+ emit statistics_update(stalled_cycles(), speed_improvement(), usage_efficiency());
+}
diff --git a/qtmips_machine/cache.h b/qtmips_machine/cache.h
index d7bd967..6cf3a2c 100644
--- a/qtmips_machine/cache.h
+++ b/qtmips_machine/cache.h
@@ -11,7 +11,7 @@ namespace machine {
class Cache : public MemoryAccess {
Q_OBJECT
public:
- Cache(Memory *m, const MachineConfigCache *c);
+ Cache(Memory *m, const MachineConfigCache *c, unsigned memory_access_penalty_r = 1, unsigned memory_access_penalty_w = 1);
void wword(std::uint32_t address, std::uint32_t value);
std::uint32_t rword(std::uint32_t address) const;
@@ -21,6 +21,9 @@ public:
unsigned hit() const; // Number of recorded hits
unsigned miss() const; // Number of recorded misses
+ unsigned stalled_cycles() const; // Number of wasted cycles in memory waitin statistic
+ double speed_improvement() const; // Speed improvement in percents in comare with no used cache
+ double usage_efficiency() const; // Usage efficiency in percents
void reset(); // Reset whole state of cache
@@ -29,11 +32,13 @@ public:
signals:
void hit_update(unsigned) const;
void miss_update(unsigned) const;
+ void statistics_update(unsigned stalled_cycles, double speed_improv, double usage_effic) const;
void cache_update(unsigned associat, unsigned set, bool valid, bool dirty, std::uint32_t tag, const std::uint32_t *data) const;
private:
MachineConfigCache cnf;
Memory *mem;
+ unsigned access_pen_r, access_pen_w;
struct cache_data {
bool valid, dirty;
@@ -47,11 +52,12 @@ private:
unsigned **lfu; // Access count
} replc; // Data used for replacement policy
- mutable unsigned hitc, missc; // Hit and miss counters
+ mutable unsigned hit_read, miss_read, hit_write, miss_write; // Hit and miss counters
void access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value = 0) const;
void kick(unsigned associat_indx, unsigned row) const;
std::uint32_t base_address(std::uint32_t tag, unsigned row) const;
+ void update_statistics() const;
};
}
diff --git a/qtmips_machine/machineconfig.cpp b/qtmips_machine/machineconfig.cpp
index 13a1ff2..9329795 100644
--- a/qtmips_machine/machineconfig.cpp
+++ b/qtmips_machine/machineconfig.cpp
@@ -284,11 +284,11 @@ bool MachineConfig::memory_write_protection() const {
}
unsigned MachineConfig::memory_access_time_read() const {
- return mem_acc_read;
+ return mem_acc_read > 1 ? mem_acc_read : 1;
}
unsigned MachineConfig::memory_access_time_write() const {
- return mem_acc_write;
+ return mem_acc_write > 1 ? mem_acc_write : 1;
}
QString MachineConfig::elf() const {
diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp
index 4a2b0f2..da4516a 100644
--- a/qtmips_machine/qtmipsmachine.cpp
+++ b/qtmips_machine/qtmipsmachine.cpp
@@ -13,8 +13,8 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) : QObject(), mcnf(&cc) {
regs = new Registers();
mem = new Memory(*mem_program_only);
- cch_program = new Cache(mem, &cc.cache_program());
- cch_data = new Cache(mem, &cc.cache_data());
+ cch_program = new Cache(mem, &cc.cache_program(), cc.memory_access_time_read(), cc.memory_access_time_write());
+ cch_data = new Cache(mem, &cc.cache_data(), cc.memory_access_time_read(), cc.memory_access_time_write());
if (cc.pipelined())
cr = new CorePipelined(regs, cch_program, cch_data, cc.hazard_unit());