Merge branch 'develop' into work/new_json_format_rebased
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
* Eder F. Zulian
|
||||
* Derek Christ
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
@@ -221,7 +222,9 @@ void TlmRecorder::terminateRemainingTransactions()
|
||||
{
|
||||
while (!currentTransactionsInSystem.empty())
|
||||
{
|
||||
auto transaction = currentTransactionsInSystem.begin();
|
||||
auto transaction = std::min_element(currentTransactionsInSystem.begin(),
|
||||
currentTransactionsInSystem.end(), [](decltype(currentTransactionsInSystem)::value_type& l,
|
||||
decltype(currentTransactionsInSystem)::value_type& r) -> bool {return l.second.id < r.second.id;});
|
||||
if (transaction->second.cmd == 'X')
|
||||
{
|
||||
std::string beginPhase = transaction->second.recordedPhases.front().name;
|
||||
@@ -307,10 +310,8 @@ void TlmRecorder::prepareSqlStatements()
|
||||
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, "
|
||||
":maxBufferDepth, :per2BankOffset)";
|
||||
|
||||
insertCommandLengthsString =
|
||||
"INSERT INTO CommandLengths VALUES"
|
||||
"(:NOP, :RD, :WR, :RDA, :WRA, :ACT, :PREPB, :REFPB, :RFMPB, :REFP2B, :RFMP2B, :PRESB, :REFSB, :RFMSB, "
|
||||
":PREAB, :REFAB, :RFMAB, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)";
|
||||
insertCommandLengthsString = "INSERT INTO CommandLengths VALUES"
|
||||
"(:command, :length)";
|
||||
|
||||
insertDebugMessageString =
|
||||
"INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
|
||||
@@ -371,31 +372,17 @@ void TlmRecorder::insertCommandLengths()
|
||||
{
|
||||
const MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 1, static_cast<int>(lround(memSpec->getCommandLength(Command::NOP) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2, static_cast<int>(lround(memSpec->getCommandLength(Command::RD) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 3, static_cast<int>(lround(memSpec->getCommandLength(Command::WR) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 4, static_cast<int>(lround(memSpec->getCommandLength(Command::RDA) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 5, static_cast<int>(lround(memSpec->getCommandLength(Command::WRA) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 6, static_cast<int>(lround(memSpec->getCommandLength(Command::ACT) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 7, static_cast<int>(lround(memSpec->getCommandLength(Command::PREPB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 8, static_cast<int>(lround(memSpec->getCommandLength(Command::REFPB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 9, static_cast<int>(lround(memSpec->getCommandLength(Command::RFMPB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 10, static_cast<int>(lround(memSpec->getCommandLength(Command::REFP2B) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 11, static_cast<int>(lround(memSpec->getCommandLength(Command::RFMP2B) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 12, static_cast<int>(lround(memSpec->getCommandLength(Command::PRESB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 13, static_cast<int>(lround(memSpec->getCommandLength(Command::REFSB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 14, static_cast<int>(lround(memSpec->getCommandLength(Command::RFMSB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 15, static_cast<int>(lround(memSpec->getCommandLength(Command::PREAB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 16, static_cast<int>(lround(memSpec->getCommandLength(Command::REFAB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 17, static_cast<int>(lround(memSpec->getCommandLength(Command::RFMAB) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 18, static_cast<int>(lround(memSpec->getCommandLength(Command::PDEA) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 19, static_cast<int>(lround(memSpec->getCommandLength(Command::PDXA) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 20, static_cast<int>(lround(memSpec->getCommandLength(Command::PDEP) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 21, static_cast<int>(lround(memSpec->getCommandLength(Command::PDXP) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 22, static_cast<int>(lround(memSpec->getCommandLength(Command::SREFEN) / memSpec->tCK)));
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 23, static_cast<int>(lround(memSpec->getCommandLength(Command::SREFEX) / memSpec->tCK)));
|
||||
auto insertCommandLength = [this, memSpec](Command command) {
|
||||
auto commandName = command.toString();
|
||||
|
||||
executeSqlStatement(insertCommandLengthsStatement);
|
||||
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
|
||||
sqlite3_bind_int(insertCommandLengthsStatement, 2,
|
||||
static_cast<int>(lround(memSpec->getCommandLength(command) / memSpec->tCK)));
|
||||
executeSqlStatement(insertCommandLengthsStatement);
|
||||
};
|
||||
|
||||
for (unsigned int command = 0; command < Command::END_ENUM; ++command)
|
||||
insertCommandLength(static_cast<Command::Type>(command));
|
||||
}
|
||||
|
||||
void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
* Matthias Jung
|
||||
* Eder F. Zulian
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef TLMRECORDER_H
|
||||
@@ -153,123 +154,102 @@ private:
|
||||
insertBufferDepthString, insertBandwidthString;
|
||||
|
||||
std::string initialCommand =
|
||||
"DROP TABLE IF EXISTS Phases; \n"
|
||||
"DROP TABLE IF EXISTS GeneralInfo; \n"
|
||||
"DROP TABLE IF EXISTS CommandLengths; \n"
|
||||
"DROP TABLE IF EXISTS Comments; \n"
|
||||
"DROP TABLE IF EXISTS ranges; \n"
|
||||
"DROP TABLE IF EXISTS Transactions; \n"
|
||||
"DROP TABLE IF EXISTS DebugMessages; \n"
|
||||
"DROP TABLE IF EXISTS Power; \n"
|
||||
"DROP TABLE IF EXISTS BufferDepth; \n"
|
||||
"DROP TABLE IF EXISTS Bandwidth; \n"
|
||||
" \n"
|
||||
"CREATE TABLE Phases( \n"
|
||||
" ID INTEGER PRIMARY KEY, \n"
|
||||
" PhaseName TEXT, \n"
|
||||
" PhaseBegin INTEGER, \n"
|
||||
" PhaseEnd INTEGER, \n"
|
||||
" Transact INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE GeneralInfo( \n"
|
||||
" NumberOfTransactions INTEGER, \n"
|
||||
" TraceEnd INTEGER, \n"
|
||||
" NumberOfRanks INTEGER, \n"
|
||||
" NumberOfBankgroups INTEGER, \n"
|
||||
" NumberOfBanks INTEGER, \n"
|
||||
" clk INTEGER, \n"
|
||||
" UnitOfTime TEXT, \n"
|
||||
" MCconfig TEXT, \n"
|
||||
" Memspec TEXT, \n"
|
||||
" Traces TEXT, \n"
|
||||
" WindowSize INTEGER, \n"
|
||||
" RefreshMaxPostponed INTEGER, \n"
|
||||
" RefreshMaxPulledin INTEGER, \n"
|
||||
" ControllerThread INTEGER, \n"
|
||||
" MaxBufferDepth INTEGER, \n"
|
||||
" Per2BankOffset INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE CommandLengths( \n"
|
||||
" NOP INTEGER, \n"
|
||||
" RD INTEGER, \n"
|
||||
" WR INTEGER, \n"
|
||||
" RDA INTEGER, \n"
|
||||
" WRA INTEGER, \n"
|
||||
" ACT INTEGER, \n"
|
||||
" PREPB INTEGER, \n"
|
||||
" REFPB INTEGER, \n"
|
||||
" RFMPB INTEGER, \n"
|
||||
" REFP2B INTEGER, \n"
|
||||
" RFMP2B INTEGER, \n"
|
||||
" PRESB INTEGER, \n"
|
||||
" REFSB INTEGER, \n"
|
||||
" RFMSB INTEGER, \n"
|
||||
" PREAB INTEGER, \n"
|
||||
" REFAB INTEGER, \n"
|
||||
" RFMAB INTEGER, \n"
|
||||
" PDEA INTEGER, \n"
|
||||
" PDXA INTEGER, \n"
|
||||
" PDEP INTEGER, \n"
|
||||
" PDXP INTEGER, \n"
|
||||
" SREFEN INTEGER, \n"
|
||||
" SREFEX INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Power( \n"
|
||||
" time DOUBLE, \n"
|
||||
" AveragePower DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE BufferDepth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" BufferNumber INTEGER, \n"
|
||||
" AverageBufferDepth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Bandwidth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" AverageBandwidth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Comments( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Text TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE DebugMessages( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Message TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)\n"
|
||||
"CREATE VIRTUAL TABLE ranges USING rtree( \n"
|
||||
" id, \n"
|
||||
" begin, end \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Transactions( \n"
|
||||
" ID INTEGER, \n"
|
||||
" Range INTEGER, \n"
|
||||
" Address INTEGER, \n"
|
||||
" Burstlength INTEGER, \n"
|
||||
" TThread INTEGER, \n"
|
||||
" TChannel INTEGER, \n"
|
||||
" TRank INTEGER, \n"
|
||||
" TBankgroup INTEGER, \n"
|
||||
" TBank INTEGER, \n"
|
||||
" TRow INTEGER, \n"
|
||||
" TColumn INTEGER, \n"
|
||||
" DataStrobeBegin INTEGER, \n"
|
||||
" DataStrobeEnd INTEGER, \n"
|
||||
" TimeOfGeneration INTEGER, \n"
|
||||
" Command TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE INDEX ranges_index ON Transactions(Range); \n"
|
||||
"CREATE INDEX \"phasesTransactions\" ON \"Phases\" (\"Transact\" ASC); \n"
|
||||
"CREATE INDEX \"messageTimes\" ON \"DebugMessages\" (\"Time\" ASC); \n";
|
||||
"DROP TABLE IF EXISTS Phases; \n"
|
||||
"DROP TABLE IF EXISTS GeneralInfo; \n"
|
||||
"DROP TABLE IF EXISTS CommandLengths; \n"
|
||||
"DROP TABLE IF EXISTS Comments; \n"
|
||||
"DROP TABLE IF EXISTS ranges; \n"
|
||||
"DROP TABLE IF EXISTS Transactions; \n"
|
||||
"DROP TABLE IF EXISTS DebugMessages; \n"
|
||||
"DROP TABLE IF EXISTS Power; \n"
|
||||
"DROP TABLE IF EXISTS BufferDepth; \n"
|
||||
"DROP TABLE IF EXISTS Bandwidth; \n"
|
||||
" \n"
|
||||
"CREATE TABLE Phases( \n"
|
||||
" ID INTEGER PRIMARY KEY, \n"
|
||||
" PhaseName TEXT, \n"
|
||||
" PhaseBegin INTEGER, \n"
|
||||
" PhaseEnd INTEGER, \n"
|
||||
" Transact INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE GeneralInfo( \n"
|
||||
" NumberOfTransactions INTEGER, \n"
|
||||
" TraceEnd INTEGER, \n"
|
||||
" NumberOfRanks INTEGER, \n"
|
||||
" NumberOfBankgroups INTEGER, \n"
|
||||
" NumberOfBanks INTEGER, \n"
|
||||
" clk INTEGER, \n"
|
||||
" UnitOfTime TEXT, \n"
|
||||
" MCconfig TEXT, \n"
|
||||
" Memspec TEXT, \n"
|
||||
" Traces TEXT, \n"
|
||||
" WindowSize INTEGER, \n"
|
||||
" RefreshMaxPostponed INTEGER, \n"
|
||||
" RefreshMaxPulledin INTEGER, \n"
|
||||
" ControllerThread INTEGER, \n"
|
||||
" MaxBufferDepth INTEGER, \n"
|
||||
" Per2BankOffset INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE CommandLengths( \n"
|
||||
" Command TEXT, \n"
|
||||
" Length INTEGER \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Power( \n"
|
||||
" time DOUBLE, \n"
|
||||
" AveragePower DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE BufferDepth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" BufferNumber INTEGER, \n"
|
||||
" AverageBufferDepth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Bandwidth( \n"
|
||||
" Time DOUBLE, \n"
|
||||
" AverageBandwidth DOUBLE \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Comments( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Text TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE DebugMessages( \n"
|
||||
" Time INTEGER, \n"
|
||||
" Message TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"-- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html)\n"
|
||||
"CREATE VIRTUAL TABLE ranges USING rtree( \n"
|
||||
" id, \n"
|
||||
" begin, end \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE Transactions( \n"
|
||||
" ID INTEGER, \n"
|
||||
" Range INTEGER, \n"
|
||||
" Address INTEGER, \n"
|
||||
" Burstlength INTEGER, \n"
|
||||
" TThread INTEGER, \n"
|
||||
" TChannel INTEGER, \n"
|
||||
" TRank INTEGER, \n"
|
||||
" TBankgroup INTEGER, \n"
|
||||
" TBank INTEGER, \n"
|
||||
" TRow INTEGER, \n"
|
||||
" TColumn INTEGER, \n"
|
||||
" DataStrobeBegin INTEGER, \n"
|
||||
" DataStrobeEnd INTEGER, \n"
|
||||
" TimeOfGeneration INTEGER, \n"
|
||||
" Command TEXT \n"
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE INDEX ranges_index ON Transactions(Range); \n"
|
||||
"CREATE INDEX \"phasesTransactions\" ON \"Phases\" (\"Transact\" ASC); \n"
|
||||
"CREATE INDEX \"messageTimes\" ON \"DebugMessages\" (\"Time\" ASC); \n";
|
||||
};
|
||||
|
||||
#endif // TLMRECORDER_H
|
||||
|
||||
@@ -96,6 +96,15 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name &name,
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSys::end_of_simulation()
|
||||
{
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
dram->reportPower();
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSys::logo()
|
||||
{
|
||||
#define GREENTXT(s) std::string(("\u001b[38;5;28m"+std::string((s))+"\033[0m"))
|
||||
|
||||
@@ -70,6 +70,8 @@ protected:
|
||||
const DRAMSysConfiguration::Configuration &config,
|
||||
bool initAndBind);
|
||||
|
||||
void end_of_simulation() override;
|
||||
|
||||
//TLM 2.0 Protocol Checkers
|
||||
std::vector<tlm_utils::tlm2_base_protocol_checker<>*> controllersTlmCheckers;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name,
|
||||
|
||||
void DRAMSysRecordable::end_of_simulation()
|
||||
{
|
||||
// Report power before TLM recorders are deleted
|
||||
// Report power before TLM recorders are finalized
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
|
||||
@@ -48,13 +48,14 @@ public:
|
||||
DRAMSysRecordable(const sc_core::sc_module_name &name,
|
||||
const DRAMSysConfiguration::Configuration &configuration);
|
||||
|
||||
protected:
|
||||
void end_of_simulation() override;
|
||||
|
||||
private:
|
||||
// Transaction Recorders (one per channel).
|
||||
// They generate the output databases.
|
||||
std::vector<TlmRecorder> tlmRecorders;
|
||||
|
||||
void end_of_simulation() override;
|
||||
|
||||
void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration);
|
||||
|
||||
void instantiateModules(const std::string &traceName,
|
||||
|
||||
@@ -95,38 +95,28 @@ Dram::Dram(const sc_module_name &name) : sc_module(name), tSocket("socket")
|
||||
|
||||
Dram::~Dram()
|
||||
{
|
||||
if (Configuration::getInstance().powerAnalysis)
|
||||
{
|
||||
Dram::reportPower();
|
||||
delete DRAMPower;
|
||||
}
|
||||
|
||||
if (Configuration::getInstance().useMalloc)
|
||||
free(memory);
|
||||
}
|
||||
|
||||
void Dram::reportPower()
|
||||
{
|
||||
if (!powerReported)
|
||||
{
|
||||
powerReported = true;
|
||||
DRAMPower->calcEnergy();
|
||||
DRAMPower->calcEnergy();
|
||||
|
||||
// Print the final total energy and the average power for
|
||||
// the simulation:
|
||||
std::cout << name() << std::string(" Total Energy: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getEnergy().total_energy
|
||||
* Configuration::getInstance().memSpec->numberOfDevices
|
||||
<< std::string(" pJ")
|
||||
<< std::endl;
|
||||
// Print the final total energy and the average power for
|
||||
// the simulation:
|
||||
std::cout << name() << std::string(" Total Energy: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getEnergy().total_energy
|
||||
* Configuration::getInstance().memSpec->numberOfDevices
|
||||
<< std::string(" pJ")
|
||||
<< std::endl;
|
||||
|
||||
std::cout << name() << std::string(" Average Power: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getPower().average_power
|
||||
* Configuration::getInstance().memSpec->numberOfDevices
|
||||
<< std::string(" mW") << std::endl;
|
||||
}
|
||||
std::cout << name() << std::string(" Average Power: ")
|
||||
<< std::fixed << std::setprecision( 2 )
|
||||
<< DRAMPower->getPower().average_power
|
||||
* Configuration::getInstance().memSpec->numberOfDevices
|
||||
<< std::string(" mW") << std::endl;
|
||||
}
|
||||
|
||||
tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload,
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#ifndef DRAM_H
|
||||
#define DRAM_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
@@ -49,9 +51,6 @@
|
||||
|
||||
class Dram : public sc_core::sc_module
|
||||
{
|
||||
private:
|
||||
bool powerReported = false;
|
||||
|
||||
protected:
|
||||
explicit Dram(const sc_core::sc_module_name &name);
|
||||
SC_HAS_PROCESS(Dram);
|
||||
@@ -63,7 +62,7 @@ protected:
|
||||
|
||||
unsigned char *memory;
|
||||
|
||||
libDRAMPower *DRAMPower = nullptr;
|
||||
std::unique_ptr<libDRAMPower> DRAMPower;
|
||||
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase, sc_core::sc_time &delay);
|
||||
|
||||
@@ -138,6 +138,6 @@ DramDDR3::DramDDR3(const sc_module_name &name) : Dram(name)
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
powerSpec.memArchSpec = memArchSpec;
|
||||
|
||||
DRAMPower = new libDRAMPower(powerSpec, false);
|
||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,6 @@ DramDDR4::DramDDR4(const sc_module_name &name) : Dram(name)
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
powerSpec.memArchSpec = memArchSpec;
|
||||
|
||||
DRAMPower = new libDRAMPower(powerSpec, false);
|
||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name)
|
||||
powerSpec.memPowerSpec = memPowerSpec;
|
||||
powerSpec.memArchSpec = memArchSpec;
|
||||
|
||||
DRAMPower = new libDRAMPower(powerSpec, false);
|
||||
DRAMPower = std::unique_ptr<libDRAMPower>(new libDRAMPower(powerSpec, false));
|
||||
|
||||
// For each bank in a channel a error Model is created:
|
||||
if (storeMode == Configuration::StoreMode::ErrorModel)
|
||||
@@ -148,7 +148,7 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name)
|
||||
{
|
||||
errorModel *em;
|
||||
std::string errorModelStr = "errorModel_bank" + std::to_string(i);
|
||||
em = new errorModel(errorModelStr.c_str(), DRAMPower);
|
||||
em = new errorModel(errorModelStr.c_str(), DRAMPower.get());
|
||||
ememory.push_back(em);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ protected:
|
||||
friend class PhaseDependency;
|
||||
};
|
||||
|
||||
class REQ : public Phase
|
||||
class REQ final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -136,8 +136,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RESP : public Phase
|
||||
class RESP final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -158,7 +157,7 @@ protected:
|
||||
|
||||
};
|
||||
/*
|
||||
class PREB: public Phase
|
||||
class PREB final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -173,7 +172,7 @@ protected:
|
||||
}
|
||||
};
|
||||
*/
|
||||
class PREPB : public Phase
|
||||
class PREPB final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -188,7 +187,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class PRESB : public Phase
|
||||
class PRESB final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -216,7 +215,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class PREAB : public Phase
|
||||
class PREAB final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -244,7 +243,7 @@ protected:
|
||||
}
|
||||
};
|
||||
/*
|
||||
class ACTB : public Phase
|
||||
class ACTB final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -259,7 +258,7 @@ protected:
|
||||
}
|
||||
};
|
||||
*/
|
||||
class ACT : public Phase
|
||||
class ACT final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -274,7 +273,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class RD : public Phase
|
||||
class RD final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -289,7 +288,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class RDA : public Phase
|
||||
class RDA final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -304,7 +303,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class WR : public Phase
|
||||
class WR final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -319,7 +318,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class WRA : public Phase
|
||||
class WRA final : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
@@ -360,7 +359,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class REFAB : public AUTO_REFRESH
|
||||
class REFAB final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -375,7 +374,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class RFMAB : public AUTO_REFRESH
|
||||
class RFMAB final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -396,8 +395,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class REFPB : public AUTO_REFRESH
|
||||
class REFPB final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -408,7 +406,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class REFP2B : public AUTO_REFRESH
|
||||
class REFP2B final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -423,7 +421,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class RFMP2B : public AUTO_REFRESH
|
||||
class RFMP2B final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -444,7 +442,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class REFSB : public AUTO_REFRESH
|
||||
class REFSB final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -459,7 +457,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class RFMSB : public AUTO_REFRESH
|
||||
class RFMSB final : public AUTO_REFRESH
|
||||
{
|
||||
public:
|
||||
using AUTO_REFRESH::AUTO_REFRESH;
|
||||
@@ -484,6 +482,8 @@ class PDNAB : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
virtual ~PDNAB() = default;
|
||||
|
||||
protected:
|
||||
QString Name() const override
|
||||
{
|
||||
@@ -508,7 +508,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class PDNA : public PDNAB
|
||||
class PDNA final : public PDNAB
|
||||
{
|
||||
public:
|
||||
using PDNAB::PDNAB;
|
||||
@@ -527,6 +527,8 @@ class PDNPB : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
virtual ~PDNPB() = default;
|
||||
|
||||
protected:
|
||||
QString Name() const override
|
||||
{
|
||||
@@ -551,7 +553,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class PDNP : public PDNPB
|
||||
class PDNP final : public PDNPB
|
||||
{
|
||||
public:
|
||||
using PDNPB::PDNPB;
|
||||
@@ -570,6 +572,8 @@ class SREFB : public Phase
|
||||
{
|
||||
public:
|
||||
using Phase::Phase;
|
||||
virtual ~SREFB() = default;
|
||||
|
||||
protected:
|
||||
QString Name() const override
|
||||
{
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PythonCaller &PythonCaller::instance()
|
||||
{
|
||||
static PythonCaller instance;
|
||||
@@ -98,21 +96,20 @@ PythonCaller::PythonCaller() :
|
||||
|
||||
|
||||
//returns new reference to the function (see: http://edcjones.tripod.com/refcount.html for the difference between "new reference" and "borrowed reference")
|
||||
PyObject *PythonCaller::loadFunctionFromModule(string moduleName,
|
||||
string functionName)
|
||||
PyObject *PythonCaller::loadFunctionFromModule(std::string moduleName, std::string functionName)
|
||||
{
|
||||
PyObject *pModuleName = PyUnicode_FromString(moduleName.c_str());
|
||||
PyObject *pModule = PyImport_Import(pModuleName);
|
||||
|
||||
if (!pModule) {
|
||||
throw runtime_error(string("Could not load module " + moduleName));
|
||||
throw std::runtime_error(std::string("Could not load module " + moduleName));
|
||||
}
|
||||
|
||||
PyObject *pFunction = PyObject_GetAttrString(pModule, functionName.c_str());
|
||||
|
||||
if (!pFunction || !PyCallable_Check(pFunction)) {
|
||||
throw runtime_error(string("Could not load test function " + functionName +
|
||||
"in module " + moduleName));
|
||||
throw std::runtime_error(
|
||||
std::string("Could not load test function " + functionName + "in module " + moduleName));
|
||||
}
|
||||
|
||||
Py_DECREF(pModuleName);
|
||||
@@ -134,8 +131,7 @@ PythonCaller::~PythonCaller()
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
PyObject *PythonCaller::callMetricsFunction(PyObject *function,
|
||||
QString argument, vector<long> list)
|
||||
PyObject *PythonCaller::callMetricsFunction(PyObject *function, QString argument, std::vector<long> list)
|
||||
{
|
||||
assert(PyCallable_Check(function));
|
||||
|
||||
@@ -153,8 +149,7 @@ PyObject *PythonCaller::callMetricsFunction(PyObject *function,
|
||||
|
||||
if (!pResult) {
|
||||
PyErr_Print();
|
||||
throw runtime_error(string("Error in calling " + testFunctionName +
|
||||
" in module " + testModuleName));
|
||||
throw std::runtime_error(std::string("Error in calling " + testFunctionName + " in module " + testModuleName));
|
||||
}
|
||||
|
||||
return pResult;
|
||||
@@ -174,8 +169,7 @@ PyObject *PythonCaller::callFunctionWithStringArgument(PyObject *function,
|
||||
|
||||
if (!pResult) {
|
||||
PyErr_Print();
|
||||
throw runtime_error(string("Error in calling " + testFunctionName +
|
||||
" in module " + testModuleName));
|
||||
throw std::runtime_error(std::string("Error in calling " + testFunctionName + " in module " + testModuleName));
|
||||
}
|
||||
|
||||
return pResult;
|
||||
@@ -188,7 +182,7 @@ PyObject *PythonCaller::callFunctionWithoutArguments(PyObject *function)
|
||||
|
||||
if (!pResult) {
|
||||
PyErr_Print();
|
||||
throw runtime_error(string("Error in calling python function"));
|
||||
throw std::runtime_error(std::string("Error in calling python function"));
|
||||
}
|
||||
|
||||
return pResult;
|
||||
@@ -212,8 +206,7 @@ TraceTestResults PythonCaller::runTestsOnTrace(QString pathToTrace)
|
||||
return traceTestResult;
|
||||
}
|
||||
|
||||
TraceCalculatedMetrics PythonCaller::calculateMetricsOnTrace(
|
||||
QString pathToTrace, vector<long> list)
|
||||
TraceCalculatedMetrics PythonCaller::calculateMetricsOnTrace(QString pathToTrace, std::vector<long> list)
|
||||
{
|
||||
TraceCalculatedMetrics result(QFileInfo(pathToTrace).baseName());
|
||||
PyObject *pResult = callMetricsFunction(pCalculateMetricsFunction, pathToTrace,
|
||||
@@ -230,9 +223,9 @@ TraceCalculatedMetrics PythonCaller::calculateMetricsOnTrace(
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<string> PythonCaller::getMetrics(QString pathToTrace)
|
||||
std::vector<std::string> PythonCaller::getMetrics(QString pathToTrace)
|
||||
{
|
||||
vector<string> result;
|
||||
std::vector<std::string> result;
|
||||
PyObject *pResult = callFunctionWithStringArgument(pGetMetricsFunction,
|
||||
pathToTrace);
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ class PythonCaller
|
||||
{
|
||||
public:
|
||||
static PythonCaller &instance();
|
||||
PythonCaller(const PythonCaller &other) = delete;
|
||||
|
||||
TraceTestResults runTestsOnTrace(QString pathToTrace);
|
||||
TraceCalculatedMetrics calculateMetricsOnTrace(QString pathToTrace,
|
||||
@@ -70,6 +69,8 @@ public:
|
||||
private:
|
||||
PythonCaller();
|
||||
~PythonCaller();
|
||||
PythonCaller(const PythonCaller &other) = delete;
|
||||
PythonCaller &operator=(const PythonCaller &other) = delete;
|
||||
|
||||
PyObject *pRunTestsFunction, *pCalculateMetricsFunction, *pGetMetricsFunction;
|
||||
PyObject *pGenPlotsFunction;
|
||||
|
||||
@@ -334,101 +334,80 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
|
||||
CommandLengths TraceDB::getCommandLengthsFromDB()
|
||||
{
|
||||
QVariant parameter;
|
||||
parameter = getParameterFromTable("NOP", "CommandLengths");
|
||||
unsigned NOP = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("RD", "CommandLengths");
|
||||
unsigned RD = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("WR", "CommandLengths");
|
||||
unsigned WR = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("RDA", "CommandLengths");
|
||||
unsigned RDA = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("WRA", "CommandLengths");
|
||||
unsigned WRA = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("ACT", "CommandLengths");
|
||||
unsigned ACT = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PREPB", "CommandLengths");
|
||||
unsigned PREPB;
|
||||
if (parameter.isValid())
|
||||
const std::string table = "CommandLengths";
|
||||
|
||||
auto getLengthFromDb = [=, &table](const std::string &command) -> QVariant
|
||||
{
|
||||
PREPB = parameter.toUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = getParameterFromTable("PRE", "CommandLengths");
|
||||
if (parameter.isValid())
|
||||
PREPB = parameter.toUInt();
|
||||
QSqlQuery query(("SELECT Length FROM " + table + " WHERE Command = \"" + command + "\"").c_str(), database);
|
||||
|
||||
if (query.first())
|
||||
return query.value(0);
|
||||
else
|
||||
PREPB = 1;
|
||||
}
|
||||
parameter = getParameterFromTable("REFPB", "CommandLengths");
|
||||
unsigned REFPB;
|
||||
if (parameter.isValid())
|
||||
return {};
|
||||
};
|
||||
|
||||
auto getCommandLength = [=, &table](const std::string &command) -> unsigned
|
||||
{
|
||||
REFPB = parameter.toUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = getParameterFromTable("REFB", "CommandLengths");
|
||||
if (parameter.isValid())
|
||||
REFPB = parameter.toUInt();
|
||||
QVariant length = getLengthFromDb(command);
|
||||
|
||||
if (length.isValid())
|
||||
return length.toUInt();
|
||||
else
|
||||
REFPB = 1;
|
||||
}
|
||||
parameter = getParameterFromTable("RFMPB", "CommandLengths");
|
||||
unsigned RFMPB = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("REFP2B", "CommandLengths");
|
||||
unsigned REFP2B = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("RFMP2B", "CommandLengths");
|
||||
unsigned RFMP2B = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PRESB", "CommandLengths");
|
||||
unsigned PRESB = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("REFSB", "CommandLengths");
|
||||
unsigned REFSB = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("RFMSB", "CommandLengths");
|
||||
unsigned RFMSB = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PREAB", "CommandLengths");
|
||||
unsigned PREAB;
|
||||
if (parameter.isValid())
|
||||
{
|
||||
qDebug() << "CommandLength for" << command.c_str() << "not present in table" << table.c_str()
|
||||
<< ". Defaulting to 1.";
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
auto getCommandLengthOrElse = [=, &table](const std::string &command, const std::string &elseCommand) -> unsigned
|
||||
{
|
||||
PREAB = parameter.toUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = getParameterFromTable("PREA", "CommandLengths");
|
||||
if (parameter.isValid())
|
||||
PREAB = parameter.toUInt();
|
||||
QVariant length = getLengthFromDb(command);
|
||||
|
||||
if (length.isValid())
|
||||
return length.toUInt();
|
||||
else
|
||||
PREAB = 1;
|
||||
}
|
||||
parameter = getParameterFromTable("REFAB", "CommandLengths");
|
||||
unsigned REFAB;
|
||||
if (parameter.isValid())
|
||||
{
|
||||
REFAB = parameter.toUInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = getParameterFromTable("REFA", "CommandLengths");
|
||||
if (parameter.isValid())
|
||||
REFAB = parameter.toUInt();
|
||||
else
|
||||
REFAB = 1;
|
||||
}
|
||||
parameter = getParameterFromTable("RFMAB", "CommandLengths");
|
||||
unsigned RFMAB = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PDEA", "CommandLengths");
|
||||
unsigned PDEA = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PDXA", "CommandLengths");
|
||||
unsigned PDXA = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PDEP", "CommandLengths");
|
||||
unsigned PDEP = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("PDXP", "CommandLengths");
|
||||
unsigned PDXP = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("SREFEN", "CommandLengths");
|
||||
unsigned SREFEN = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("SREFEX", "CommandLengths");
|
||||
unsigned SREFEX = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
{
|
||||
length = getLengthFromDb(command);
|
||||
|
||||
if (length.isValid())
|
||||
return length.toUInt();
|
||||
else
|
||||
{
|
||||
qDebug() << "CommandLength for" << command.c_str() << "and" << elseCommand.c_str()
|
||||
<< "not present in table" << table.c_str() << ". Defaulting to 1.";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unsigned NOP = getCommandLength("NOP");
|
||||
unsigned RD = getCommandLength("RD");
|
||||
unsigned WR = getCommandLength("RD");
|
||||
unsigned RDA = getCommandLength("RDA");
|
||||
unsigned WRA = getCommandLength("WRA");
|
||||
unsigned ACT = getCommandLength("ACT");
|
||||
|
||||
unsigned PREPB = getCommandLengthOrElse("PREPB", "PRE");
|
||||
unsigned REFPB = getCommandLengthOrElse("REFPB", "REFB");
|
||||
|
||||
unsigned RFMPB = getCommandLength("RFMPB");
|
||||
unsigned REFP2B = getCommandLength("REFP2B");
|
||||
unsigned RFMP2B = getCommandLength("RFMP2B");
|
||||
unsigned PRESB = getCommandLength("PRESB");
|
||||
unsigned REFSB = getCommandLength("REFSB");
|
||||
unsigned RFMSB = getCommandLength("RFMSB");
|
||||
|
||||
unsigned PREAB = getCommandLengthOrElse("PREAB", "PREA");
|
||||
unsigned REFAB = getCommandLengthOrElse("REFAB", "REFA");
|
||||
|
||||
unsigned RFMAB = getCommandLength("RFMAB");
|
||||
unsigned PDEA = getCommandLength("PDEA");
|
||||
unsigned PDXA = getCommandLength("PDXA");
|
||||
unsigned PDEP = getCommandLength("PDEP");
|
||||
unsigned PDXP = getCommandLength("PDXP");
|
||||
unsigned SREFEN = getCommandLength("SREFEN");
|
||||
unsigned SREFEX = getCommandLength("SREFEX");
|
||||
|
||||
return {NOP, RD, WR, RDA, WRA, ACT, PREPB, REFPB, RFMPB, REFP2B, RFMP2B, PRESB, REFSB, RFMSB,
|
||||
PREAB, REFAB, RFMAB, PDEA, PDXA, PDEP, PDXP, SREFEN, SREFEX};
|
||||
|
||||
@@ -115,7 +115,7 @@ private:
|
||||
QString pathToDB;
|
||||
QSqlDatabase database;
|
||||
GeneralInfo generalInfo;
|
||||
CommandLengths commandLengths{};
|
||||
CommandLengths commandLengths;
|
||||
|
||||
QSqlQuery insertPhaseQuery;
|
||||
QSqlQuery insertTransactionQuery;
|
||||
|
||||
@@ -54,6 +54,12 @@ def getNumberOfTransactions(dbconnection):
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
def getTraceEndTime(dbconnection):
|
||||
cursor = dbconnection.cursor()
|
||||
cursor.execute("SELECT TraceEnd FROM GeneralInfo")
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
def getNumberOfBanks(dbconnection):
|
||||
cursor = dbconnection.cursor()
|
||||
cursor.execute("SELECT NumberOfBanks FROM generalInfo")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import sys
|
||||
import sqlite3
|
||||
import argparse
|
||||
from memUtil import *
|
||||
from math import *
|
||||
|
||||
@@ -35,6 +36,27 @@ def trace_length_in_ns(connection):
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
|
||||
@metric
|
||||
def command_bus_utilisation_in_percent(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
SUM(CommandLengths.Length)
|
||||
FROM
|
||||
Phases
|
||||
INNER JOIN
|
||||
CommandLengths
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
""")
|
||||
result = cursor.fetchone()[0]
|
||||
|
||||
if (result is None):
|
||||
result = 0
|
||||
|
||||
clk, _ = getClock(connection)
|
||||
traceEnd = getTraceEndTime(connection)
|
||||
cmdBusOccupied = result * clk
|
||||
return cmdBusOccupied / traceEnd * 100
|
||||
|
||||
@metric
|
||||
def average_response_latency_in_ns(connection):
|
||||
@@ -44,11 +66,94 @@ def average_response_latency_in_ns(connection):
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
@metric
|
||||
def average_rd_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
AVG(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "R"
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
@metric
|
||||
def average_wr_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
AVG(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "W"
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
@metric
|
||||
def max_rd_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
max(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "R"
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
@metric
|
||||
def max_wr_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
max(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND Transactions.Command = "W"
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
return round(result[0], 1)
|
||||
|
||||
@metric
|
||||
def max_response_latency_in_ns(connection):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(""" SELECT max(RESP.PHASEBEGIN - REQ.PHASEBEGIN)/1000 FROM PHASES REQ, PHASES RESP
|
||||
cursor.execute(""" SELECT max(RESP.PHASEBEGIN - REQ.PHASEBEGIN)/1000 FROM PHASES REQ, PHASES RESP
|
||||
WHERE REQ.PHASENAME = 'REQ' AND RESP.PHASENAME='RESP' AND REQ.TRANSACT = RESP.TRANSACT """)
|
||||
result = cursor.fetchone()
|
||||
return result[0]
|
||||
@@ -995,8 +1100,6 @@ def calculateMetricsFromFuncs(pathToTrace, selectedMetrics):
|
||||
connection.close()
|
||||
return calculatedMetrics
|
||||
|
||||
import argparse
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
Only non-threaded metrics are implemented for selection through command line
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import sys
|
||||
import sqlite3
|
||||
from memUtil import *
|
||||
from math import *
|
||||
import ntpath
|
||||
import os
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from memUtil import *
|
||||
from math import *
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
numberOfBins = "auto"
|
||||
latencyRange = None
|
||||
|
||||
plots = []
|
||||
|
||||
def plot(function):
|
||||
plots.append(function)
|
||||
return function
|
||||
|
||||
def getThreads(connection):
|
||||
cursor = connection.cursor()
|
||||
@@ -77,11 +84,57 @@ def calculate_bandwidth_util(connection, windowSize, steps, queryFull, queryEnd,
|
||||
|
||||
|
||||
def memory_utilisation_window_thread(connection, tracePath, steps, thread_ID):
|
||||
# All possible cases of data transfers inside a time window
|
||||
queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeEnd <= ? and TThread = {0}""" # The data transfer begins and ends inside the time window
|
||||
queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=? and TThread = {0}""" # Only the end of the data transfer is inside the time window
|
||||
queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ? and TThread = {0}""" # Only the beginning of the data transfer is inside the time window
|
||||
queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ? and TThread = {0}""" # The data transfer occupies all the time window
|
||||
## All possible cases of data transfers inside a time window:
|
||||
|
||||
# The data transfer begins and ends inside the time window
|
||||
queryFull = """
|
||||
SELECT
|
||||
SUM(DataStrobeEnd - DataStrobeBegin)
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin >= ?
|
||||
AND DataStrobeEnd <= ?
|
||||
AND TThread = {0}
|
||||
"""
|
||||
|
||||
# Only the end of the data transfer is inside the time window
|
||||
queryEnd = """
|
||||
SELECT
|
||||
SUM(DataStrobeEnd - ? )
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin < ?
|
||||
AND DataStrobeEnd > ?
|
||||
AND DataStrobeEnd <=?
|
||||
AND TThread = {0}
|
||||
"""
|
||||
|
||||
# Only the beginning of the data transfer is inside the time window
|
||||
queryBegin = """
|
||||
SELECT
|
||||
SUM( ? - DataStrobeBegin)
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin >= ?
|
||||
AND DataStrobeBegin < ?
|
||||
AND DataStrobeEnd > ?
|
||||
AND TThread = {0}
|
||||
"""
|
||||
|
||||
# The data transfer occupies all the time window
|
||||
queryPart = """
|
||||
SELECT
|
||||
DataStrobeBegin
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin <= ?
|
||||
AND DataStrobeEnd >= ?
|
||||
AND TThread = {0}
|
||||
"""
|
||||
|
||||
queryFull = queryFull.format(thread_ID)
|
||||
queryEnd = queryEnd.format(thread_ID)
|
||||
@@ -95,13 +148,7 @@ def memory_utilisation_window_thread(connection, tracePath, steps, thread_ID):
|
||||
outputFileNameBWMatlab, basename = createOutputFilename(tracePath, 'memory_utilization_percent', 'thread_' + str(thread_ID) + '_', 'txt')
|
||||
return bandwidthPercentage, bandwidth, outputFileNameBWMatlab
|
||||
|
||||
|
||||
def plot(function):
|
||||
plots.append(function)
|
||||
return function
|
||||
|
||||
|
||||
#@plot
|
||||
@plot
|
||||
def memory_utilisation_window(connection, tracePath, steps):
|
||||
# This function determines the average memory bandwidth over time in
|
||||
# percentage and in Gbit/s. The average bandwidth over time is done
|
||||
@@ -118,11 +165,53 @@ def memory_utilisation_window(connection, tracePath, steps):
|
||||
windowSize = getWindowSize(connection)
|
||||
maxDataRate = maximum_data_rate(connection)
|
||||
|
||||
# All possible cases of data transfers inside a time window
|
||||
queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeEnd <= ?""" # The data transfer begins and ends inside the time window
|
||||
queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window
|
||||
queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window
|
||||
queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window
|
||||
## All possible cases of data transfers inside a time window:
|
||||
|
||||
# The data transfer begins and ends inside the time window
|
||||
queryFull = """
|
||||
SELECT
|
||||
SUM(DataStrobeEnd - DataStrobeBegin)
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin >= ?
|
||||
AND DataStrobeEnd <= ?
|
||||
"""
|
||||
|
||||
# Only the end of the data transfer is inside the time window
|
||||
queryEnd = """
|
||||
SELECT
|
||||
SUM(DataStrobeEnd - ?)
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin < ?
|
||||
AND DataStrobeEnd > ?
|
||||
AND DataStrobeEnd <= ?
|
||||
"""
|
||||
|
||||
# Only the beginning of the data transfer is inside the time window
|
||||
queryBegin = """
|
||||
SELECT
|
||||
SUM(? - DataStrobeBegin)
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin >= ?
|
||||
AND DataStrobeBegin < ?
|
||||
AND DataStrobeEnd > ?
|
||||
"""
|
||||
|
||||
# The data transfer occupies all the time window
|
||||
queryPart = """
|
||||
SELECT
|
||||
DataStrobeBegin
|
||||
FROM
|
||||
transactions
|
||||
WHERE
|
||||
DataStrobeBegin <= ?
|
||||
AND DataStrobeEnd >= ?
|
||||
"""
|
||||
|
||||
bandwidthPercentage, bandwidth, maximumPercentage = calculate_bandwidth_util(connection, windowSize, steps, queryFull, queryEnd, queryBegin, queryPart)
|
||||
|
||||
@@ -131,10 +220,6 @@ def memory_utilisation_window(connection, tracePath, steps):
|
||||
outputFileNameBWMatlab, basename = createOutputFilename(tracePath, 'memory_utilization_percent', '', 'txt')
|
||||
outputFiles = "{0}\n\t{1}\n\t{2}\n\t".format(outputFileNameGBPS, outputFileNamePercent, outputFileNameBWMatlab)
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
# windowSize/1000: picoseconds to nanoseconds conversion
|
||||
time = np.arange(0, (steps+1)*windowSize/1000, windowSize/1000)
|
||||
maxBandwidth = [maxDataRate/1024] * (steps+1)
|
||||
@@ -196,12 +281,238 @@ def memory_utilisation_window(connection, tracePath, steps):
|
||||
|
||||
return outputFiles
|
||||
|
||||
@plot
|
||||
def response_latency_window(connection, tracePath, steps):
|
||||
windowSize = getWindowSize(connection)
|
||||
|
||||
cursor = connection.cursor()
|
||||
query = """
|
||||
SELECT
|
||||
avg(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND RESP.PHASEBEGIN >= ? and RESP.PHASEEND <= ?
|
||||
"""
|
||||
outputFileName, basename = createOutputFilename(tracePath, 'response_latency', '', 'pdf')
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
|
||||
LatencyFigure = plt.figure(figsize=(10, 5), dpi=300)
|
||||
LatencyFigurePlot = LatencyFigure.add_subplot(111)
|
||||
LatencyFigurePlot.set_xlabel('Time [ns]')
|
||||
LatencyFigurePlot.set_ylabel('Response Latency [ns]')
|
||||
LatencyFigurePlot.set_title('Average Response Latency: ' + str(basename))
|
||||
LatencyFigurePlot.grid(True)
|
||||
|
||||
time = [None] * steps
|
||||
latency = [None] * steps
|
||||
|
||||
for i in range(steps):
|
||||
cursor.execute(query, (i * windowSize, (i + 1) * windowSize))
|
||||
result = cursor.fetchone()[0]
|
||||
time[i] = ((i * windowSize) - (windowSize / 2)) / 1000 # ps to ns
|
||||
latency[i] = result
|
||||
|
||||
LatencyFigurePlot.plot(time, latency, linewidth=0.5, label="Latency")
|
||||
LatencyFigurePlot.legend(loc="upper left")
|
||||
|
||||
pdf = PdfPages(outputFileName)
|
||||
pdf.savefig(LatencyFigure)
|
||||
pdf.close()
|
||||
LatencyFigurePlot.clear()
|
||||
plt.close()
|
||||
|
||||
return outputFile
|
||||
|
||||
@plot
|
||||
def wr_response_latency_window(connection, tracePath, steps):
|
||||
windowSize = getWindowSize(connection)
|
||||
|
||||
cursor = connection.cursor()
|
||||
query = """
|
||||
SELECT
|
||||
avg(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND RESP.PHASEBEGIN >= ? and RESP.PHASEEND <= ?
|
||||
AND Transactions.Command = "W"
|
||||
"""
|
||||
outputFileName, basename = createOutputFilename(tracePath, 'wr_response_latency', '', 'pdf')
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
|
||||
LatencyFigure = plt.figure(figsize=(10, 5), dpi=300)
|
||||
LatencyFigurePlot = LatencyFigure.add_subplot(111)
|
||||
LatencyFigurePlot.set_xlabel('Time [ns]')
|
||||
LatencyFigurePlot.set_ylabel('Response Latency [ns]')
|
||||
LatencyFigurePlot.set_title('Average Write Response Latency: ' + str(basename))
|
||||
LatencyFigurePlot.grid(True)
|
||||
|
||||
time = [None] * steps
|
||||
latency = [None] * steps
|
||||
|
||||
for i in range(steps):
|
||||
cursor.execute(query, (i * windowSize, (i + 1) * windowSize))
|
||||
result = cursor.fetchone()[0]
|
||||
time[i] = ((i * windowSize) - (windowSize / 2)) / 1000 # ps to ns
|
||||
latency[i] = result
|
||||
|
||||
LatencyFigurePlot.plot(time, latency, linewidth=0.5, label="Latency")
|
||||
LatencyFigurePlot.legend(loc="upper left")
|
||||
|
||||
pdf = PdfPages(outputFileName)
|
||||
pdf.savefig(LatencyFigure)
|
||||
pdf.close()
|
||||
LatencyFigurePlot.clear()
|
||||
plt.close()
|
||||
|
||||
return outputFile
|
||||
|
||||
@plot
|
||||
def rd_response_latency_window(connection, tracePath, steps):
|
||||
windowSize = getWindowSize(connection)
|
||||
|
||||
cursor = connection.cursor()
|
||||
query = """
|
||||
SELECT
|
||||
avg(RESP.PHASEBEGIN - REQ.PHASEBEGIN) / 1000
|
||||
FROM
|
||||
PHASES REQ,
|
||||
PHASES RESP
|
||||
INNER JOIN
|
||||
Transactions
|
||||
ON REQ.TRANSACT = Transactions.ID
|
||||
WHERE
|
||||
REQ.PHASENAME = 'REQ'
|
||||
AND RESP.PHASENAME = 'RESP'
|
||||
AND REQ.TRANSACT = RESP.TRANSACT
|
||||
AND RESP.PHASEBEGIN >= ? and RESP.PHASEEND <= ?
|
||||
AND Transactions.Command = "R"
|
||||
"""
|
||||
outputFileName, basename = createOutputFilename(tracePath, 'rd_response_latency', '', 'pdf')
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
|
||||
LatencyFigure = plt.figure(figsize=(10, 5), dpi=300)
|
||||
LatencyFigurePlot = LatencyFigure.add_subplot(111)
|
||||
LatencyFigurePlot.set_xlabel('Time [ns]')
|
||||
LatencyFigurePlot.set_ylabel('Response Latency [ns]')
|
||||
LatencyFigurePlot.set_title('Average Read Response Latency: ' + str(basename))
|
||||
LatencyFigurePlot.grid(True)
|
||||
|
||||
time = [None] * steps
|
||||
latency = [None] * steps
|
||||
|
||||
for i in range(steps):
|
||||
cursor.execute(query, (i * windowSize, (i + 1) * windowSize))
|
||||
result = cursor.fetchone()[0]
|
||||
time[i] = ((i * windowSize) - (windowSize / 2)) / 1000 # ps to ns
|
||||
latency[i] = result
|
||||
|
||||
LatencyFigurePlot.plot(time, latency, linewidth=0.5, label="Latency")
|
||||
LatencyFigurePlot.legend(loc="upper left")
|
||||
|
||||
pdf = PdfPages(outputFileName)
|
||||
pdf.savefig(LatencyFigure)
|
||||
pdf.close()
|
||||
LatencyFigurePlot.clear()
|
||||
plt.close()
|
||||
|
||||
return outputFile
|
||||
|
||||
@plot
|
||||
def command_bus_utilisation_window(connection, tracePath, steps):
|
||||
windowSize = getWindowSize(connection)
|
||||
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Query that sums all lengths that are completely contained in the window
|
||||
query_full = """
|
||||
SELECT
|
||||
SUM(CommandLengths.Length)
|
||||
FROM
|
||||
Phases,
|
||||
GeneralInfo
|
||||
INNER JOIN
|
||||
CommandLengths
|
||||
ON Phases.PhaseName = CommandLengths.Command
|
||||
WHERE
|
||||
Phases.PhaseBegin >= ?
|
||||
AND (Phases.PhaseBegin + (CommandLengths.Length * GeneralInfo.clk)) < ?
|
||||
"""
|
||||
|
||||
# Gets the PhaseBegin of the command that reaches out of the window
|
||||
# query_border = """
|
||||
# SELECT
|
||||
# Phases.PhaseBegin
|
||||
# FROM
|
||||
# Phases,
|
||||
# GeneralInfo
|
||||
# INNER JOIN
|
||||
# CommandLengths
|
||||
# ON Phases.PhaseName = CommandLengths.Command
|
||||
# WHERE
|
||||
# Phases.PhaseBegin >= ?
|
||||
# AND Phases.PhaseBegin < ?
|
||||
# AND (Phases.PhaseBegin + (CommandLengths.Length * GeneralInfo.clk)) >= ?
|
||||
# """
|
||||
|
||||
outputFileName, basename = createOutputFilename(tracePath, 'command_bus_utilisation', '', 'pdf')
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
|
||||
LatencyFigure = plt.figure(figsize=(10, 5), dpi=300)
|
||||
LatencyFigurePlot = LatencyFigure.add_subplot(111)
|
||||
LatencyFigurePlot.set_xlabel('Time [ns]')
|
||||
LatencyFigurePlot.set_ylabel('Utilization [%]')
|
||||
LatencyFigurePlot.set_title('Command Bus Utilization: ' + str(basename))
|
||||
LatencyFigurePlot.grid(True)
|
||||
|
||||
clk, _ = getClock(connection)
|
||||
|
||||
time = [None] * steps
|
||||
utilization = [None] * steps
|
||||
|
||||
for i in range(steps):
|
||||
left_limit = i * windowSize
|
||||
right_limit = (i + 1) * windowSize
|
||||
|
||||
cursor.execute(query_full, (left_limit, right_limit))
|
||||
result = cursor.fetchone()[0]
|
||||
|
||||
if (result is None):
|
||||
result = 0
|
||||
|
||||
cmdBusOccupied = result * clk
|
||||
|
||||
time[i] = ((i * windowSize) - (windowSize / 2)) / 1000 # ps to ns
|
||||
utilization[i] = cmdBusOccupied / windowSize * 100
|
||||
|
||||
if (utilization[i] > 100):
|
||||
print(left_limit, right_limit)
|
||||
|
||||
LatencyFigurePlot.plot(time, utilization, linewidth=0.5, label="Utilization")
|
||||
LatencyFigurePlot.legend(loc="upper left")
|
||||
|
||||
pdf = PdfPages(outputFileName)
|
||||
pdf.savefig(LatencyFigure)
|
||||
pdf.close()
|
||||
LatencyFigurePlot.clear()
|
||||
plt.close()
|
||||
|
||||
return outputFile
|
||||
|
||||
@plot
|
||||
def queue_window(connection, tracePath, steps):
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select max(BufferNumber) from BufferDepth;")
|
||||
bufferNumber = int(cursor.fetchone()[0]) + 1
|
||||
@@ -256,7 +567,6 @@ def power_window(connection, tracePath, steps):
|
||||
|
||||
cursor.execute(" SELECT * FROM Power")
|
||||
|
||||
import numpy as np
|
||||
window = float(windowSize) / pow(10, 12)
|
||||
time = np.arange(0, (windowSize * (steps + 1)) / pow(10, 6), windowSize / pow(10, 6))
|
||||
power = np.full(len(time), 0)
|
||||
@@ -282,9 +592,6 @@ def power_window(connection, tracePath, steps):
|
||||
outputFileName, basename = createOutputFilename(tracePath, 'power', '', 'pdf')
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
PowFigure = plt.figure(figsize=(10, 5), dpi=300)
|
||||
PowFigurePlot = PowFigure.add_subplot(111)
|
||||
PowFigurePlot.set_xlabel('Time [us]')
|
||||
@@ -301,104 +608,6 @@ def power_window(connection, tracePath, steps):
|
||||
|
||||
return outputFile
|
||||
|
||||
def latency_analysis(connection, tracePath, steps):
|
||||
from collections import Counter
|
||||
query = """ SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000), t.id
|
||||
FROM Transactions t, Phases p1, Phases p2
|
||||
WHERE t.id = p1.Transact
|
||||
AND t.id = p2.Transact
|
||||
AND p1.PhaseName = "REQ"
|
||||
AND p2.PhaseName = "RESP" """
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
results = []
|
||||
while True:
|
||||
result = cursor.fetchone()
|
||||
if (result is not None):
|
||||
results.append([result[0], result[1]])
|
||||
else:
|
||||
break
|
||||
|
||||
# Create histogram for analysis:
|
||||
hist = {}
|
||||
transactions = {}
|
||||
for i in results:
|
||||
hist[i[0]] = hist.get(i[0], 0) + 1
|
||||
if i[0] in transactions:
|
||||
transactions[i[0]].append(i[1])
|
||||
else:
|
||||
transactions[i[0]] = []
|
||||
|
||||
# Find N highest bins
|
||||
N = 3
|
||||
k = Counter(hist)
|
||||
high = k.most_common(3)
|
||||
|
||||
for i in high:
|
||||
print(i[0]," :",i[1]," ")
|
||||
print(transactions[i[0]])
|
||||
|
||||
return "none\n"
|
||||
|
||||
#@plot
|
||||
def latency_histogram(connection, tracePath, steps):
|
||||
# This function plots an histogram with access latencys
|
||||
|
||||
def plot_latency_histogram(dataArray, outputFileName, basename):
|
||||
# plot into PDF file
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
plt.hist(dataArray, bins=numberOfBins, range=latencyRange, histtype='bar', facecolor='green')
|
||||
plt.grid(True)
|
||||
plt.xlabel("Access Time [ns]")
|
||||
plt.ylabel("Number of Accesses (Frequency)")
|
||||
plt.title("Latency Histogram " + str(basename))
|
||||
pdf = PdfPages(outputFileName)
|
||||
pdf.savefig()
|
||||
pdf.close()
|
||||
plt.close()
|
||||
|
||||
def create_latency_hist(connection, tracePath, target_measurement, query):
|
||||
# form output file name
|
||||
ofbname = 'access_latency_hist'
|
||||
outputFileName, basename = createOutputFilename(tracePath, ofbname, target_measurement, 'pdf')
|
||||
# return log string
|
||||
outputFile = "{0}\n\t".format(outputFileName)
|
||||
# access database
|
||||
resultArray = accessDatabase(connection, query)
|
||||
# plot
|
||||
plot_latency_histogram(resultArray, outputFileName, basename)
|
||||
return outputFile
|
||||
|
||||
# create overal latency histogram
|
||||
query = """ SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000)
|
||||
FROM Transactions t, Phases p1, Phases p2
|
||||
WHERE t.id = p1.Transact
|
||||
AND t.id = p2.Transact
|
||||
AND p1.PhaseName = "REQ"
|
||||
AND p2.PhaseName = "RESP" """
|
||||
outputFile = create_latency_hist(connection, tracePath, '', query)
|
||||
|
||||
# create per-thread latency histogram
|
||||
threads = getThreads(connection)
|
||||
if (len(threads) > 1):
|
||||
queryThread = """ SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000)
|
||||
FROM Transactions t, Phases p1, Phases p2
|
||||
WHERE t.id = p1.Transact
|
||||
AND t.id = p2.Transact
|
||||
AND p1.PhaseName = "REQ"
|
||||
AND p2.PhaseName = "RESP"
|
||||
AND t.TThread = {0} """
|
||||
for thread in threads:
|
||||
thrname = 'thread_' + str(thread) + '_'
|
||||
outputFile += create_latency_hist(connection, tracePath, thrname, queryThread.format(thread))
|
||||
|
||||
return outputFile
|
||||
|
||||
|
||||
def generatePlots(pathToTrace):
|
||||
connection = sqlite3.connect(pathToTrace)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user