Merge branch 'fix/bandwidth' into 'develop'

Fix for bandwidth calculations with pseudo-channels

See merge request ems/astdm/modeling.dram/dram.sys.5!87
This commit is contained in:
Lukas Steiner
2024-11-29 08:48:37 +00:00
22 changed files with 105 additions and 52 deletions

View File

@@ -506,11 +506,13 @@ def memory_utilisation_in_Gibps_without_idle(connection):
def memory_utilisation_percent_including_idle(connection): def memory_utilisation_percent_including_idle(connection):
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("""SELECT SUM(DataStrobeEnd - DataStrobeBegin) FROM Phases""") cursor.execute("""SELECT SUM(DataStrobeEnd - DataStrobeBegin) FROM Phases""")
active = cursor.fetchone() active = cursor.fetchone()[0]
if getPseudoChannelMode(connection):
active /= 2
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute("""SELECT MAX(DataStrobeEnd) FROM Phases""") cursor.execute("""SELECT MAX(DataStrobeEnd) FROM Phases""")
total = cursor.fetchone() total = cursor.fetchone()[0]
return (active[0] / total[0]) * 100 return (active / total) * 100
# def refreshMissDecision(connection, calculatedMetrics): # def refreshMissDecision(connection, calculatedMetrics):

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecDDR5::MemSpecDDR5(const Config::MemSpec& memSpec) : MemSpecDDR5::MemSpecDDR5(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -49,7 +49,6 @@ MemSpecHBM3::MemSpecHBM3(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") / memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
@@ -140,6 +139,11 @@ bool MemSpecHBM3::hasRasAndCasBus() const
return true; return true;
} }
bool MemSpecHBM3::pseudoChannelMode() const
{
return true;
}
sc_time MemSpecHBM3::getExecutionTime(Command command, const tlm_generic_payload& payload) const sc_time MemSpecHBM3::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{ {
if (command == Command::PREPB || command == Command::PREAB) if (command == Command::PREPB || command == Command::PREAB)

View File

@@ -97,6 +97,7 @@ public:
[[nodiscard]] unsigned getRAAMMT() const override; [[nodiscard]] unsigned getRAAMMT() const override;
[[nodiscard]] bool hasRasAndCasBus() const override; [[nodiscard]] bool hasRasAndCasBus() const override;
[[nodiscard]] bool pseudoChannelMode() const override;
[[nodiscard]] sc_core::sc_time [[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override; getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;

View File

@@ -48,7 +48,6 @@ namespace DRAMSys
MemSpecLPDDR5::MemSpecLPDDR5(const Config::MemSpec& memSpec) : MemSpecLPDDR5::MemSpecLPDDR5(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -472,18 +472,8 @@ void TlmRecorder::insertGeneralInfo(const std::string& mcConfigString,
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(mcConfig.requestBufferSize)); sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(mcConfig.requestBufferSize));
sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast<int>(memSpec.getPer2BankOffset())); sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast<int>(memSpec.getPer2BankOffset()));
const auto memoryType = memSpec.memoryType; bool rowColumnCommandBus = memSpec.hasRasAndCasBus();
bool pseudoChannelMode = memSpec.pseudoChannelMode();
bool rowColumnCommandBus =
(memoryType == Config::MemoryType::HBM2) || (memoryType == Config::MemoryType::HBM3);
bool pseudoChannelMode = [this, memoryType]() -> bool
{
if (memoryType != Config::MemoryType::HBM2 && memoryType != Config::MemoryType::HBM3)
return false;
return memSpec.pseudoChannelsPerChannel != 1;
}();
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(rowColumnCommandBus)); sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(rowColumnCommandBus));
sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(pseudoChannelMode)); sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(pseudoChannelMode));

View File

@@ -44,7 +44,6 @@ namespace DRAMSys
MemSpec::MemSpec(const Config::MemSpec& memSpec, MemSpec::MemSpec(const Config::MemSpec& memSpec,
unsigned numberOfChannels, unsigned numberOfChannels,
unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned ranksPerChannel,
unsigned banksPerRank, unsigned banksPerRank,
unsigned groupsPerRank, unsigned groupsPerRank,
@@ -53,7 +52,6 @@ MemSpec::MemSpec(const Config::MemSpec& memSpec,
unsigned bankGroupsPerChannel, unsigned bankGroupsPerChannel,
unsigned devicesPerRank) : unsigned devicesPerRank) :
numberOfChannels(numberOfChannels), numberOfChannels(numberOfChannels),
pseudoChannelsPerChannel(pseudoChannelsPerChannel),
ranksPerChannel(ranksPerChannel), ranksPerChannel(ranksPerChannel),
banksPerRank(banksPerRank), banksPerRank(banksPerRank),
groupsPerRank(groupsPerRank), groupsPerRank(groupsPerRank),
@@ -150,6 +148,11 @@ bool MemSpec::hasRasAndCasBus() const
return false; return false;
} }
bool MemSpec::pseudoChannelMode() const
{
return false;
}
bool MemSpec::requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const bool MemSpec::requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const
{ {
if (allBytesEnabled(payload)) if (allBytesEnabled(payload))

View File

@@ -64,7 +64,6 @@ public:
virtual ~MemSpec() = default; virtual ~MemSpec() = default;
const unsigned numberOfChannels; const unsigned numberOfChannels;
const unsigned pseudoChannelsPerChannel;
const unsigned ranksPerChannel; const unsigned ranksPerChannel;
const unsigned banksPerRank; const unsigned banksPerRank;
const unsigned groupsPerRank; const unsigned groupsPerRank;
@@ -101,6 +100,7 @@ public:
[[nodiscard]] virtual unsigned getRAADEC() const; [[nodiscard]] virtual unsigned getRAADEC() const;
[[nodiscard]] virtual bool hasRasAndCasBus() const; [[nodiscard]] virtual bool hasRasAndCasBus() const;
[[nodiscard]] virtual bool pseudoChannelMode() const;
[[nodiscard]] virtual sc_core::sc_time [[nodiscard]] virtual sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const = 0; getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const = 0;
@@ -119,7 +119,6 @@ public:
protected: protected:
MemSpec(const Config::MemSpec& memSpec, MemSpec(const Config::MemSpec& memSpec,
unsigned numberOfChannels, unsigned numberOfChannels,
unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned ranksPerChannel,
unsigned banksPerRank, unsigned banksPerRank,
unsigned groupsPerRank, unsigned groupsPerRank,

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecDDR3::MemSpecDDR3(const Config::MemSpec& memSpec) : MemSpecDDR3::MemSpecDDR3(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1, 1,

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecDDR4::MemSpecDDR4(const Config::MemSpec& memSpec) : MemSpecDDR4::MemSpecDDR4(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecGDDR5::MemSpecGDDR5(const Config::MemSpec& memSpec) : MemSpecGDDR5::MemSpecGDDR5(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecGDDR5X::MemSpecGDDR5X(const Config::MemSpec& memSpec) : MemSpecGDDR5X::MemSpecGDDR5X(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecGDDR6::MemSpecGDDR6(const Config::MemSpec& memSpec) : MemSpecGDDR6::MemSpecGDDR6(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),

View File

@@ -50,7 +50,6 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"), memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") / memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
@@ -129,6 +128,11 @@ bool MemSpecHBM2::hasRasAndCasBus() const
return true; return true;
} }
bool MemSpecHBM2::pseudoChannelMode() const
{
return ranksPerChannel != 1;
}
sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload& payload) const sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{ {
if (command == Command::PREPB || command == Command::PREAB) if (command == Command::PREPB || command == Command::PREAB)

View File

@@ -89,6 +89,7 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override; [[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override;
[[nodiscard]] bool hasRasAndCasBus() const override; [[nodiscard]] bool hasRasAndCasBus() const override;
[[nodiscard]] bool pseudoChannelMode() const override;
[[nodiscard]] sc_core::sc_time [[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override; getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecLPDDR4::MemSpecLPDDR4(const Config::MemSpec& memSpec) : MemSpecLPDDR4::MemSpecLPDDR4(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1, 1,

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecSTTMRAM::MemSpecSTTMRAM(const Config::MemSpec& memSpec) : MemSpecSTTMRAM::MemSpecSTTMRAM(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1, 1,

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecWideIO::MemSpecWideIO(const Config::MemSpec& memSpec) : MemSpecWideIO::MemSpecWideIO(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1, 1,

View File

@@ -49,7 +49,6 @@ namespace DRAMSys
MemSpecWideIO2::MemSpecWideIO2(const Config::MemSpec& memSpec) : MemSpecWideIO2::MemSpecWideIO2(const Config::MemSpec& memSpec) :
MemSpec(memSpec, MemSpec(memSpec,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"), memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1, 1,

View File

@@ -64,6 +64,9 @@
#include "DRAMSys/controller/scheduler/SchedulerFrFcfsGrp.h" #include "DRAMSys/controller/scheduler/SchedulerFrFcfsGrp.h"
#include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfs.h" #include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfs.h"
#include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfsWm.h" #include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfsWm.h"
#include <cstdint>
#include <numeric>
#include <string>
#ifdef DDR5_SIM #ifdef DDR5_SIM
#include "DRAMSys/controller/checker/CheckerDDR5.h" #include "DRAMSys/controller/checker/CheckerDDR5.h"
@@ -89,6 +92,7 @@ Controller::Controller(const sc_module_name& name,
config(config), config(config),
memSpec(memSpec), memSpec(memSpec),
addressDecoder(addressDecoder), addressDecoder(addressDecoder),
numberOfBeatsServed(memSpec.ranksPerChannel, 0),
minBytesPerBurst(memSpec.defaultBytesPerBurst), minBytesPerBurst(memSpec.defaultBytesPerBurst),
maxBytesPerBurst(memSpec.maxBytesPerBurst) maxBytesPerBurst(memSpec.maxBytesPerBurst)
{ {
@@ -640,8 +644,14 @@ void Controller::manageResponses()
if (nextTransInRespQueue != nullptr) if (nextTransInRespQueue != nullptr)
{ {
// Ignore ECC requests // Ignore ECC requests
// TODO in future, use a tagging mechanism to distinguish between normal, ECC and maybe
// masked requests
if (nextTransInRespQueue->get_extension<EccExtension>() == nullptr) if (nextTransInRespQueue->get_extension<EccExtension>() == nullptr)
numberOfBeatsServed += ControllerExtension::getBurstLength(*nextTransInRespQueue); {
auto rank = ControllerExtension::getRank(*nextTransInRespQueue);
numberOfBeatsServed[static_cast<std::size_t>(rank)] +=
ControllerExtension::getBurstLength(*nextTransInRespQueue);
}
if (ChildExtension::isChildTrans(*nextTransInRespQueue)) if (ChildExtension::isChildTrans(*nextTransInRespQueue))
{ {
@@ -780,8 +790,15 @@ void Controller::end_of_simulation()
{ {
idleTimeCollector.end(); idleTimeCollector.end();
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed) / memSpec.dataRate * std::uint64_t totalNumberOfBeatsServed =
memSpec.tCK / memSpec.pseudoChannelsPerChannel; std::accumulate(numberOfBeatsServed.begin(), numberOfBeatsServed.end(), 0);
sc_core::sc_time activeTime =
static_cast<double>(totalNumberOfBeatsServed) / memSpec.dataRate * memSpec.tCK;
// HBM specific, pseudo channels get averaged
if (memSpec.pseudoChannelMode())
activeTime /= memSpec.ranksPerChannel;
double bandwidth = activeTime / sc_core::sc_time_stamp(); double bandwidth = activeTime / sc_core::sc_time_stamp();
double bandwidthWoIdle = double bandwidthWoIdle =
@@ -795,23 +812,59 @@ void Controller::end_of_simulation()
// BusWidth e.g. 8 or 64 // BusWidth e.g. 8 or 64
* memSpec.bitWidth * memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM // Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank * memSpec.devicesPerRank);
// HBM specific, one or two pseudo channels per channel
* memSpec.pseudoChannelsPerChannel);
std::cout << name() << std::string(" Total Time: ") << sc_core::sc_time_stamp().to_string() // HBM specific, one or two pseudo channels per channel
<< std::endl; if (memSpec.pseudoChannelMode())
std::cout << name() << std::string(" AVG BW: ") << std::fixed << std::setprecision(2) maxBandwidth *= memSpec.ranksPerChannel;
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | " << std::setw(6)
<< (bandwidth * maxBandwidth / 8) << " GB/s | " << std::setw(6) << (bandwidth * 100) std::cout << std::left << std::setw(24) << name() << std::string(" Total Time: ")
<< " %" << std::endl; << sc_core::sc_time_stamp().to_string() << std::endl;
std::cout << name() << std::string(" AVG BW\\IDLE: ") << std::fixed << std::setprecision(2) std::cout << std::left << std::setw(24) << name() << std::string(" AVG BW: ")
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | " << std::setw(6) << std::fixed << std::setprecision(2) << std::setw(6) << (bandwidth * maxBandwidth)
<< " Gb/s | " << std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (bandwidth * 100) << " %" << std::endl;
if (memSpec.ranksPerChannel > 1)
{
for (std::size_t i = 0; i < memSpec.ranksPerChannel; i++)
{
std::string baseName = memSpec.pseudoChannelMode() ? "pc" : "ra";
std::string rankName = "." + baseName + std::to_string(i);
sc_core::sc_time rankActiveTime =
numberOfBeatsServed[i] * memSpec.tCK / memSpec.dataRate;
double rankBandwidth = rankActiveTime / sc_core::sc_time_stamp();
double rankMaxBandwidth = (
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
(1000 / memSpec.tCK.to_double())
// DataRate e.g. 2
* memSpec.dataRate
// BusWidth e.g. 8 or 64
* memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank);
std::string componentName = name() + rankName;
std::cout << std::left << std::setw(24) << componentName
<< std::string(" AVG BW: ") << std::fixed << std::setprecision(2)
<< std::setw(6) << (rankBandwidth * rankMaxBandwidth) << " Gb/s | "
<< std::setw(6) << (rankBandwidth * rankMaxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (rankBandwidth * 100) << " %" << std::endl;
}
}
std::cout << std::left << std::setw(24) << name() << std::string(" AVG BW\\IDLE: ")
<< std::fixed << std::setprecision(2) << std::setw(6)
<< (bandwidthWoIdle * maxBandwidth) << " Gb/s | " << std::setw(6)
<< (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | " << std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | " << std::setw(6)
<< (bandwidthWoIdle * 100) << " %" << std::endl; << (bandwidthWoIdle * 100) << " %" << std::endl;
std::cout << name() << std::string(" MAX BW: ") << std::fixed << std::setprecision(2) std::cout << std::left << std::setw(24) << name() << std::string(" MAX BW: ")
<< std::setw(6) << maxBandwidth << " Gb/s | " << std::setw(6) << maxBandwidth / 8 << std::fixed << std::setprecision(2) << std::setw(6) << maxBandwidth << " Gb/s | "
<< " GB/s | " << std::setw(6) << 100.0 << " %" << std::endl; << std::setw(6) << maxBandwidth / 8 << " GB/s | " << std::setw(6) << 100.0 << " %"
<< std::endl;
} }
} // namespace DRAMSys } // namespace DRAMSys

View File

@@ -101,7 +101,7 @@ protected:
sc_core::sc_time scMaxTime = sc_core::sc_max_time(); sc_core::sc_time scMaxTime = sc_core::sc_max_time();
uint64_t numberOfBeatsServed = 0; std::vector<uint64_t> numberOfBeatsServed;
unsigned totalNumberOfPayloads = 0; unsigned totalNumberOfPayloads = 0;
std::function<void()> idleCallback; std::function<void()> idleCallback;
ControllerVector<Rank, unsigned> ranksNumberOfPayloads; ControllerVector<Rank, unsigned> ranksNumberOfPayloads;

View File

@@ -113,8 +113,15 @@ void ControllerRecordable::controllerMethod()
Controller::controllerMethod(); Controller::controllerMethod();
uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed; std::uint64_t totalNumberOfBeatsServed = std::accumulate(numberOfBeatsServed.begin(), numberOfBeatsServed.end(), 0);
lastNumberOfBeatsServed = numberOfBeatsServed;
uint64_t windowNumberOfBeatsServed = totalNumberOfBeatsServed - lastNumberOfBeatsServed;
lastNumberOfBeatsServed = totalNumberOfBeatsServed;
// HBM specific, pseudo channels get averaged
if (memSpec.pseudoChannelMode())
windowNumberOfBeatsServed /= memSpec.ranksPerChannel;
sc_time windowActiveTime = sc_time windowActiveTime =
activeTimeMultiplier * static_cast<double>(windowNumberOfBeatsServed); activeTimeMultiplier * static_cast<double>(windowNumberOfBeatsServed);
double windowAverageBandwidth = windowActiveTime / windowSizeTime; double windowAverageBandwidth = windowActiveTime / windowSizeTime;