File nbhb_cache.h
File List > mem > nbhb_cache > nbhb_cache.h
Go to the documentation of this file
#pragma once
#include <simtix/mem.h>
#include <deque>
#include <string>
#include <vector>
namespace simtix {
namespace mem {
class NBHBCacheImpl {
public:
using Payload = MemoryInterface::Payload;
using OnResp = MemoryInterface::OnResp;
using RespStatus = MemoryInterface::RespStatus;
NBHBCacheImpl(const std::string &name, MemoryInterface *next_level,
const NBHBCache::Param ¶m)
: stat_(std::make_shared<Stat>(name)),
name_(name),
kBlockSizeBytes(param.kBlockSizeBytes),
kBanks(param.kBanks),
bank_occupied_(kBanks, false),
next_level_(next_level) {
for (size_t i = 0; i < kBanks; i++) {
Cache::Param bank_param = param;
bank_param.kSizeBytes = param.kSizeBytes / kBanks;
banks_.emplace_back(fmt::format("{}.bank[{}]", name, i), next_level,
bank_param);
}
for (size_t i = 0; i < kBanks; i++) {
stat_->AddStatGroup(banks_[i].stat());
}
}
// Function: ForwardRequest
// Forward the request to the corresponding bank. If the bank is occupied by
// any request, return false to indicate the request is not accepted.
bool ForwardRequest(const Payload &payload, OnResp on_resp, bool is_write);
protected:
inline uint64_t ToBankIndex(uint64_t addr) {
return addr / kBlockSizeBytes % kBanks;
}
struct Stat : stat::Group {
explicit Stat(const std::string &s)
: Group(s),
STAT(bank_conflict, "Number of bank conflicts", "N/A"),
STAT(bank_available, "Number of available banks when request is sent",
"N/A"),
STAT(total_write_requests,
"Total number of write requests send to NBHB cache", "N/A"),
STAT(total_read_requests,
"Total number of read requests send to NBHB cache", "N/A"),
STAT(forwarded_requests, "Number of forwarded requests", "N/A"),
STAT(total_requests, "Total number of requests send to NBHB cache",
"N/A"),
STAT(bank_utilization, "Bank utilization of NBHB cache", "N/A") {
total_requests = total_write_requests + total_read_requests;
bank_utilization = forwarded_requests / bank_available;
}
stat::Integer bank_conflict;
stat::Integer bank_available;
stat::Integer total_write_requests;
stat::Integer total_read_requests;
stat::Integer forwarded_requests;
stat::Formula<stat::Integer> total_requests;
stat::Formula<stat::Real> bank_utilization;
};
std::shared_ptr<Stat> stat_;
void ResetStat() {
stat_ = std::make_shared<Stat>(name_);
for (size_t i = 0; i < kBanks; i++) {
banks_[i].ResetStat();
stat_->AddStatGroup(banks_[i].stat());
}
}
const std::string name_;
const size_t kBlockSizeBytes;
const size_t kBanks;
std::deque<Cache> banks_;
std::vector<bool> bank_occupied_;
MemoryInterface *next_level_;
};
class NBHBCache::Impl : NBHBCacheImpl {
public:
Impl(const std::string &name, MemoryInterface *next_level, const Param ¶m)
: NBHBCacheImpl(name, next_level, param) {}
protected:
friend class NBHBCache;
};
} // namespace mem
} // namespace simtix