diff options
Diffstat (limited to 'qtmips_machine')
-rw-r--r-- | qtmips_machine/cache.cpp | 65 | ||||
-rw-r--r-- | qtmips_machine/cache.h | 10 | ||||
-rw-r--r-- | qtmips_machine/machineconfig.cpp | 4 | ||||
-rw-r--r-- | qtmips_machine/qtmipsmachine.cpp | 4 |
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()); |