Added main calculation loop and other modifications and corrections. Still missing table data storing and test.

This commit is contained in:
Iron Prando da Silva
2021-12-10 15:14:39 +01:00
parent b75a795779
commit 1f78932267
11 changed files with 244 additions and 97 deletions

View File

@@ -6,41 +6,41 @@ DDR3TimeDependencies::DDR3TimeDependencies(const QJsonObject& memspec) : DRAMTim
}
void DDR3TimeDependencies::mInitializeValues() {
burstLength = mMemspecJson["memarchitecturespec"].toObject()["burstLength"].toString().toLongLong();
dataRate = mMemspecJson["memarchitecturespec"].toObject()["dataRate"].toString().toLongLong();
clk = mMemspecJson["memarchitecturespec"].toArray()[0].toString().toLongLong();
burstLength = mMemspecJson["memarchitecturespec"].toObject()["burstLength"].toString().toInt();
dataRate = mMemspecJson["memarchitecturespec"].toObject()["dataRate"].toString().toInt();
clk = mMemspecJson["memarchitecturespec"].toArray()[0].toString().toInt();
nActivateWindow = 4;
tRP = mMemspecJson["memtimingspec"].toObject()["RP"].toString().toLongLong();
tRAS = mMemspecJson["memtimingspec"].toObject()["RAS"].toString().toLongLong();
tRC = mMemspecJson["memtimingspec"].toObject()["RC"].toString().toLongLong();
tRTP = mMemspecJson["memtimingspec"].toObject()["RTP"].toString().toLongLong();
tRRD = mMemspecJson["memtimingspec"].toObject()["RRD"].toString().toLongLong();
tCCD = mMemspecJson["memtimingspec"].toObject()["CCD"].toString().toLongLong();
tRCD = mMemspecJson["memtimingspec"].toObject()["RCD"].toString().toLongLong();
tNAW = mMemspecJson["memtimingspec"].toObject()["NAW"].toString().toLongLong();
tRL = mMemspecJson["memtimingspec"].toObject()["RL"].toString().toLongLong();
tWL = mMemspecJson["memtimingspec"].toObject()["WL"].toString().toLongLong();
tWR = mMemspecJson["memtimingspec"].toObject()["WR"].toString().toLongLong();
tWTR = mMemspecJson["memtimingspec"].toObject()["WTR"].toString().toLongLong();
tCKESR = mMemspecJson["memtimingspec"].toObject()["CKESR"].toString().toLongLong();
tCKE = mMemspecJson["memtimingspec"].toObject()["CKE"].toString().toLongLong();
tXP = mMemspecJson["memtimingspec"].toObject()["XP"].toString().toLongLong();
tXPDLL = mMemspecJson["memtimingspec"].toObject()["XPDLL"].toString().toLongLong();
tXS = mMemspecJson["memtimingspec"].toObject()["XS"].toString().toLongLong();
tXSDLL = mMemspecJson["memtimingspec"].toObject()["XSDLL"].toString().toLongLong();
tAL = mMemspecJson["memtimingspec"].toObject()["AL"].toString().toLongLong();
tRFC = mMemspecJson["memtimingspec"].toObject()["RFC"].toString().toLongLong();
tREFI = mMemspecJson["memtimingspec"].toObject()["REFI"].toString().toLongLong();
tRTRS = mMemspecJson["memtimingspec"].toObject()["RTRS"].toString().toLongLong();
tACTPDEN = mMemspecJson["memtimingspec"].toObject()["ACTPDEN"].toString().toLongLong();
tPRPDEN = mMemspecJson["memtimingspec"].toObject()["PRPDEN"].toString().toLongLong();
tREFPDEN = mMemspecJson["memtimingspec"].toObject()["REFPDEN"].toString().toLongLong();
tCKE = mMemspecJson["memtimingspec"].toObject()["CKE"].toString().toLongLong();
tRP = mMemspecJson["memtimingspec"].toObject()["RP"].toString().toInt();
tRAS = mMemspecJson["memtimingspec"].toObject()["RAS"].toString().toInt();
tRC = mMemspecJson["memtimingspec"].toObject()["RC"].toString().toInt();
tRTP = mMemspecJson["memtimingspec"].toObject()["RTP"].toString().toInt();
tRRD = mMemspecJson["memtimingspec"].toObject()["RRD"].toString().toInt();
tCCD = mMemspecJson["memtimingspec"].toObject()["CCD"].toString().toInt();
tRCD = mMemspecJson["memtimingspec"].toObject()["RCD"].toString().toInt();
tNAW = mMemspecJson["memtimingspec"].toObject()["NAW"].toString().toInt();
tRL = mMemspecJson["memtimingspec"].toObject()["RL"].toString().toInt();
tWL = mMemspecJson["memtimingspec"].toObject()["WL"].toString().toInt();
tWR = mMemspecJson["memtimingspec"].toObject()["WR"].toString().toInt();
tWTR = mMemspecJson["memtimingspec"].toObject()["WTR"].toString().toInt();
tCKESR = mMemspecJson["memtimingspec"].toObject()["CKESR"].toString().toInt();
tCKE = mMemspecJson["memtimingspec"].toObject()["CKE"].toString().toInt();
tXP = mMemspecJson["memtimingspec"].toObject()["XP"].toString().toInt();
tXPDLL = mMemspecJson["memtimingspec"].toObject()["XPDLL"].toString().toInt();
tXS = mMemspecJson["memtimingspec"].toObject()["XS"].toString().toInt();
tXSDLL = mMemspecJson["memtimingspec"].toObject()["XSDLL"].toString().toInt();
tAL = mMemspecJson["memtimingspec"].toObject()["AL"].toString().toInt();
tRFC = mMemspecJson["memtimingspec"].toObject()["RFC"].toString().toInt();
tREFI = mMemspecJson["memtimingspec"].toObject()["REFI"].toString().toInt();
tRTRS = mMemspecJson["memtimingspec"].toObject()["RTRS"].toString().toInt();
tACTPDEN = mMemspecJson["memtimingspec"].toObject()["ACTPDEN"].toString().toInt();
tPRPDEN = mMemspecJson["memtimingspec"].toObject()["PRPDEN"].toString().toInt();
tREFPDEN = mMemspecJson["memtimingspec"].toObject()["REFPDEN"].toString().toInt();
tCKE = mMemspecJson["memtimingspec"].toObject()["CKE"].toString().toInt();
tPD = tCKE;
tBURST = (int) ((burstLength / dataRate) * clk);
tBURST = (uint) ((burstLength / (float) dataRate) * clk);
tRDWR = tRL + tBURST + 2 * clk - tWL;
tRDWR_R = tRL + tBURST + tRTRS - tWL;
tWRRD = tWL + tBURST + tWTR;
@@ -49,6 +49,7 @@ void DDR3TimeDependencies::mInitializeValues() {
tRDPDEN = tRL + tBURST + clk;
tWRPDEN = tWL + tBURST + tWR;
tWRAPDEN = tWL + tBURST + tWR + clk;
}
DependencyMap DDR3TimeDependencies::mSpecializedGetDependencies() const {
@@ -135,6 +136,26 @@ DependencyMap DDR3TimeDependencies::mSpecializedGetDependencies() const {
)
);
dmap.emplace(
std::piecewise_construct,
std::forward_as_tuple("WRA"),
std::forward_as_tuple(
std::initializer_list<TimeDependency>{
{tRCD - tAL, "ACT", DependencyType::IntraBank, "tRCD - tAL"},
{tRDWR, "RD", DependencyType::IntraRank, "tRDWR"},
{tRDWR, "RDA", DependencyType::IntraRank, "tRDWR"},
{tCCD, "WR", DependencyType::IntraRank, "tCCD"},
{tCCD, "WRA", DependencyType::IntraRank, "tCCD"},
{tXP, "PDXA", DependencyType::IntraRank, "tXP"},
{tXSDLL, "SREFEX", DependencyType::IntraRank, "tXSDLL"},
{tRDWR_R, "RD", DependencyType::InterRank, "tRDWR_R"},
{tRDWR_R, "RDA", DependencyType::InterRank, "tRDWR_R"},
{tBURST + tRTRS, "WR", DependencyType::InterRank, "tBURST + tRTRS"},
{tBURST + tRTRS, "WRA", DependencyType::InterRank, "tBURST + tRTRS"}
}
)
);
dmap.emplace(
std::piecewise_construct,
std::forward_as_tuple("PREPB"),
@@ -182,7 +203,7 @@ DependencyMap DDR3TimeDependencies::mSpecializedGetDependencies() const {
dmap.emplace(
std::piecewise_construct,
std::forward_as_tuple("REFAB"),
std::forward_as_tuple("PDEA"),
std::forward_as_tuple(
std::initializer_list<TimeDependency>{
{tACTPDEN, "ACT", DependencyType::IntraRank, "tACTPDEN"},

View File

@@ -10,50 +10,47 @@ public:
protected:
void mInitializeValues() override;
DependencyMap mSpecializedGetDependencies() const override;
protected:
size_t burstLength;
size_t dataRate;
size_t clk;
uint burstLength;
uint dataRate;
size_t nActivateWindow;
uint tRP;
uint tRAS;
uint tRC;
uint tRTP;
uint tRRD;
uint tCCD;
uint tRCD;
uint tNAW;
uint tRL;
uint tWL;
uint tWR;
uint tWTR;
uint tCKESR;
uint tCKE;
uint tXP;
uint tXPDLL;
uint tXS;
uint tXSDLL;
uint tAL;
uint tRFC;
uint tREFI;
uint tRTRS;
size_t tRP;
size_t tRAS;
size_t tRC;
size_t tRTP;
size_t tRRD;
size_t tCCD;
size_t tRCD;
size_t tNAW;
size_t tRL;
size_t tWL;
size_t tWR;
size_t tWTR;
size_t tCKESR;
size_t tCKE;
size_t tXP;
size_t tXPDLL;
size_t tXS;
size_t tXSDLL;
size_t tAL;
size_t tRFC;
size_t tREFI;
size_t tRTRS;
uint tACTPDEN;
uint tPRPDEN;
uint tREFPDEN;
size_t tACTPDEN;
size_t tPRPDEN;
size_t tREFPDEN;
size_t tPD;
size_t tBURST;
size_t tRDWR;
size_t tRDWR_R;
size_t tWRRD;
size_t tWRRD_R;
size_t tWRPRE;
size_t tRDPDEN;
size_t tWRPDEN;
size_t tWRAPDEN;
uint tPD;
uint tBURST;
uint tRDWR;
uint tRDWR_R;
uint tWRRD;
uint tWRRD_R;
uint tWRPRE;
uint tRDPDEN;
uint tWRPDEN;
uint tWRAPDEN;
};

View File

@@ -26,8 +26,11 @@ DRAMTimeDependenciesIF::getDependencies(std::vector<QString>& dependencyFilter)
while (it != dependenciesMap.end()) {
mFilterDependencyList(it->second.dependencies, dependencyFilter);
it->second.maxTime = mFindVectorMaximum(it->second.dependencies);
++it;
}
return dependenciesMap;
}
@@ -60,7 +63,9 @@ void DRAMTimeDependenciesIF::mFilterDependencyList(std::vector<TimeDependency>&
dependencyFilter.begin(),
dependencyFilter.end(),
dep.phaseDep,
QStringsComparator::compareQStrings
[](const QString& cmd, const QString& depName){
return cmd == "NAW" || QStringsComparator::compareQStrings(cmd, depName);
}
);
if (it != dependencyFilter.end() && *it == dep.phaseDep) return true;
@@ -102,7 +107,7 @@ void DRAMTimeDependenciesIF::mFilterDependencyMap(DependencyMap& dependencyMap,
itFilterLast,
itDependencyMap,
[](const QString& cmd, const std::pair<QString, PhaseTimeDependencies>& vpair) {
return cmd == vpair.first;
return cmd.compare(vpair.first) == 0;
}
);
@@ -113,6 +118,8 @@ void DRAMTimeDependenciesIF::mFilterDependencyMap(DependencyMap& dependencyMap,
} else if (pair.first->compare(pair.second->first) < 0) {
++(pair.first);
} else if (pair.first->compare(pair.second->first) == 0) {
++(pair.second);
} else {
pair.second = dependencyMap.erase(pair.second);
@@ -123,9 +130,10 @@ void DRAMTimeDependenciesIF::mFilterDependencyMap(DependencyMap& dependencyMap,
}
}
}
size_t DRAMTimeDependenciesIF::mFindVectorMaximum(const std::vector<TimeDependency>& dependencyList) const {
uint DRAMTimeDependenciesIF::mFindVectorMaximum(const std::vector<TimeDependency>& dependencyList) const {
auto maxElement = std::max_element(
dependencyList.begin(),
dependencyList.end(),

View File

@@ -35,6 +35,7 @@ struct QStringsComparator {
typedef std::map<QString, PhaseTimeDependencies, QStringsComparator> DependencyMap;
class DRAMTimeDependenciesIF {
public:
DRAMTimeDependenciesIF(const QJsonObject& memspec);
@@ -44,10 +45,13 @@ public:
static const QJsonObject getMemspec(const TraceDB& tdb);
const uint getClk() const { return clk; }
const uint getNAW() const { return nActivateWindow; };
protected:
void mFilterDependencyList(std::vector<TimeDependency>& dependencyList, const std::vector<QString>& dependencyFilter) const;
void mFilterDependencyMap(DependencyMap& dependencyMap, const std::vector<QString>& dependencyFilter) const;
size_t mFindVectorMaximum(const std::vector<TimeDependency>& dependencyList) const;
uint mFindVectorMaximum(const std::vector<TimeDependency>& dependencyList) const;
protected:
QJsonObject mMemspecJson;
@@ -56,6 +60,9 @@ protected:
protected:
virtual void mInitializeValues() {} ;
virtual DependencyMap mSpecializedGetDependencies() const { DependencyMap map; return map; } ;
uint clk = 0;
uint nActivateWindow = 0;
};

View File

@@ -1,16 +1,16 @@
#include "dramtimedependencyfactory.h"
DRAMTimeDependenciesIF DRAMTimeDependencyFactory::make(const TraceDB& tdb) {
std::shared_ptr<DRAMTimeDependenciesIF> DRAMTimeDependencyFactory::make(const TraceDB& tdb) {
const QJsonObject& memspec = DRAMTimeDependenciesIF::getMemspec(tdb);
QString deviceType = memspec["memspec"]["memoryType"].toString();
QString deviceType = memspec["memoryType"].toString();
if (deviceType == "DDR3") {
return DDR3TimeDependencies(memspec);
return std::make_shared<DDR3TimeDependencies>(memspec);
} else {
// TODO maybe throw?
return DRAMTimeDependenciesIF(memspec);
throw std::invalid_argument("Could not find the device type '" + deviceType.toStdString() + '\'');
}

View File

@@ -1,13 +1,15 @@
#pragma once
#include <memory>
#include "dramtimedependenciesIF.h"
#include "DDR3TimeDependencies.h"
#include "data/tracedb.h"
class DRAMTimeDependencyFactory {
public:
static DRAMTimeDependenciesIF make(const TraceDB& tdb);
static std::shared_ptr<DRAMTimeDependenciesIF> make(const TraceDB& tdb);
private:
DRAMTimeDependencyFactory() = delete;

View File

@@ -2,13 +2,13 @@
#include "phasedependenciestracker.h"
void
PhaseDependenciesTracker::calculateDependencies(TraceDB& tdb, const std::vector<std::string>& commands) {
PhaseDependenciesTracker::calculateDependencies(TraceDB& tdb, std::vector<QString>& commands) {
mDropTable(tdb);
mCreateTable(tdb);
auto& phases = mGetAllPhases(tdb, commands);
auto& entries = mCalculateDependencies(tdb, phases);
auto& entries = mCalculateDependencies(tdb, phases, commands);
mInsertIntoTable(tdb, entries);
@@ -61,7 +61,7 @@ void PhaseDependenciesTracker::mInsertIntoTable(TraceDB& tdb, const std::vector<
}
const std::vector<std::shared_ptr<DBPhaseEntry>>
PhaseDependenciesTracker::mGetAllPhases(TraceDB& tdb, const std::vector<std::string>& commands) {
PhaseDependenciesTracker::mGetAllPhases(TraceDB& tdb, const std::vector<QString>& commands) {
std::vector<std::shared_ptr<DBPhaseEntry>> phases;
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TRank "
@@ -70,8 +70,8 @@ PhaseDependenciesTracker::mGetAllPhases(TraceDB& tdb, const std::vector<std::str
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
for (auto cmd : commands) {
queryStr += '\"' + QString::fromStdString(cmd + "\",");
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";
}
queryStr.back() = ')';
queryStr += " ORDER BY PhaseBegin ";
@@ -117,11 +117,104 @@ PhaseDependenciesTracker::mGetAllPhases(TraceDB& tdb, const std::vector<std::str
}
const std::vector<DBDependencyEntry>
PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::vector<std::shared_ptr<DBPhaseEntry>>& transactions) {
PhaseDependenciesTracker::mCalculateDependencies(const TraceDB& tdb, const std::vector<std::shared_ptr<DBPhaseEntry>>& phases, std::vector<QString>& commands) {
std::vector<DBDependencyEntry> entries;
DRAMTimeDependenciesIF deviceDependencies = DRAMTimeDependencyFactory::make(tdb);
// TODO Main dependency calculation loop
// Get dependencies for tdb device
auto device = DRAMTimeDependencyFactory::make(tdb);
DependencyMap deviceDependencies = device->getDependencies(commands);
// Tries to find all timing dependencies for each phase on the trace
std::vector<DBDependencyEntry> tmpPotentialNAW;
tmpPotentialNAW.reserve(16);
for (size_t i = 1; i < phases.size(); i++) {
// NAW dependencies variables reset
tmpPotentialNAW.clear();
size_t nawCount = 0;
// Auxiliary variables
const auto& phase = phases[i];
const size_t cmdBank = phase->tBank;
const size_t cmdRank = phase->tRank;
// Get time dependency descriptions for the current phase
const auto& deps = deviceDependencies.at(phase->phaseName);
// Loop all previous phases until there cannot be any more time dependencies
for (int j = i-1; j >= 0; j--) {
// Get next phase to analyse
const auto& otherPhase = phases[j];
// Calculates the time difference in nanoseconds
const auto timeDiff = phase->phaseBegin - otherPhase->phaseBegin;
// Time difference begin greater than the maximum possible dependency time ends the internal loop
if (timeDiff > deps.maxTime) break;
// For each possible dependency for the current phase,
// checks if otherPhase would match as a dependency
for (const auto& dep : deps.dependencies) {
if (dep.phaseDep != "NAW" && dep.phaseDep != otherPhase->phaseName) continue;
if (
dep.depType == DependencyType::IntraBank && cmdBank != otherPhase->tBank
|| dep.depType == DependencyType::IntraRank && cmdBank != otherPhase->tRank
|| dep.depType == DependencyType::InterRank && cmdRank == otherPhase->tRank // TODO - is this last comparison correct?
) {
continue;
}
if (dep.phaseDep == "NAW") {
if (otherPhase->phaseName == "ACT") {
if (timeDiff == dep.timeValue) {
// Captures only the first (or exactly matching time) ACT in
// the ACT window as a dependency
tmpPotentialNAW.emplace_back(DBDependencyEntry{
phase->id,
phase->phaseName,
PhaseDependency::dependencyTypeName(dep.depType),
dep.timeDepName,
otherPhase->id,
otherPhase->phaseName
});
}
nawCount++;
}
continue; // TODO should this continue here or should it be removed for potentially more time dependencies to be captured?
}
if (timeDiff == dep.timeValue) {
entries.emplace_back(DBDependencyEntry{
phase->id,
phase->phaseName,
PhaseDependency::dependencyTypeName(dep.depType),
dep.timeDepName,
otherPhase->id,
otherPhase->phaseName
});
}
}
if (timeDiff == device->getClk()) {
entries.emplace_back(DBDependencyEntry{
phase->id,
phase->phaseName,
PhaseDependency::dependencyTypeName(DependencyType::IntraRank),
"CommandBus",
otherPhase->id,
otherPhase->phaseName
});
}
}
if (nawCount >= device->getNAW()) {
entries.insert( entries.end(), tmpPotentialNAW.begin(), tmpPotentialNAW.end() );
}
}
return entries;
}

View File

@@ -29,15 +29,15 @@ struct DBDependencyEntry {
class PhaseDependenciesTracker {
public:
static void calculateDependencies(TraceDB& tdb, const std::vector<std::string>& commands);
static void calculateDependencies(TraceDB& tdb, std::vector<QString>& dependencyFilter);
private:
static void mDropTable(TraceDB& tdb);
static void mCreateTable(TraceDB& tdb);
static void mInsertIntoTable(TraceDB& tdb, const std::vector<DBDependencyEntry>& entries);
static const std::vector<std::shared_ptr<DBPhaseEntry>> mGetAllPhases(TraceDB& tdb, const std::vector<std::string>& commands);
static const std::vector<DBDependencyEntry> mCalculateDependencies(const TraceDB& tdb, const std::vector<std::shared_ptr<DBPhaseEntry>>& phases);
static const std::vector<std::shared_ptr<DBPhaseEntry>> mGetAllPhases(TraceDB& tdb, const std::vector<QString>& commands);
static const std::vector<DBDependencyEntry> mCalculateDependencies(const TraceDB& tdb, const std::vector<std::shared_ptr<DBPhaseEntry>>& phases, std::vector<QString>& commands);
static QSqlQuery mExecuteQuery(TraceDB& tdb, const QString queryStr);

View File

@@ -129,4 +129,22 @@ void PhaseDependency::mDraw(QPoint &end, double depY, const TraceDrawingProperti
drawText(painter, mTimeDependency, textPosition, alignment);
}
}
}
QString PhaseDependency::dependencyTypeName(DependencyType dtype) {
switch(dtype) {
case IntraBank:
return "IntraBank";
case IntraRank:
return "IntraRank";
case InterRank:
return "InterRank";
default:
// TODO - maybe throw?
return "";
}
}

View File

@@ -68,6 +68,8 @@ public:
bool draw(QPoint &end, const TraceDrawingProperties &drawingProperties, QPainter *painter, const QwtScaleMap &xMap,
const QwtScaleMap &yMap);
static QString dependencyTypeName(DependencyType);
protected:
DependencyType mType;
QString mTimeDependency;

View File

@@ -313,17 +313,16 @@ void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex &index)
void TraceFileTab::on_calculateDependencies_clicked() {
// TODO - anything else? Update view maybe?
// TODO - For now fixed, but must be selectable
std::vector<std::string> dependencyFilter = {
std::vector<QString> dependencyFilter = {
"ACT",
"PRE",
"PREPB",
"RD",
"RDA",
"WR",
"WRA",
"PDE",
"PDX",
"PREA",
"NAW"
"PREAB"
};
PhaseDependenciesTracker::calculateDependencies(navigator->TraceFile(), dependencyFilter);