From 9949c36f83484a8d6152a399cfed6c8c982ca5ef Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 1 Jun 2021 11:11:40 +0200 Subject: [PATCH] Use separate thread for database creation. --- DRAMSys/library/src/common/TlmRecorder.cpp | 117 ++++++++++----------- DRAMSys/library/src/common/TlmRecorder.h | 26 ++--- DRAMSys/library/src/controller/Command.h | 36 +++---- DRAMSys/simulator/StlPlayer.cpp | 6 +- 4 files changed, 89 insertions(+), 96 deletions(-) diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 7e952fa8..61f86e22 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -42,15 +42,18 @@ #include "TlmRecorder.h" #include "dramExtensions.h" #include "../configuration/Configuration.h" -#include "../controller/Command.h" using namespace tlm; TlmRecorder::TlmRecorder(const std::string &name, const std::string &dbName) : - name(name), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME) + name(name), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME) { - recordedData.reserve(transactionCommitRate); - setUpTransactionTerminatingPhases(); + currentDataBuffer = &recordingDataBuffer[0]; + storageDataBuffer = &recordingDataBuffer[1]; + + currentDataBuffer->reserve(transactionCommitRate); + storageDataBuffer->reserve(transactionCommitRate); + openDB(dbName); char *sErrMsg; sqlite3_exec(db, "PRAGMA main.page_size = 4096", nullptr, nullptr, &sErrMsg); @@ -111,29 +114,28 @@ void TlmRecorder::recordBandwidth(double timeInSeconds, double averageBandwidth) void TlmRecorder::recordPhase(tlm_generic_payload &trans, tlm_phase phase, const sc_time &time) { - if (currentTransactionsInSystem.count(&trans) == 0) + if (currentTransactionsInSystem.find(&trans) == currentTransactionsInSystem.end()) introduceTransactionSystem(trans); std::string phaseName = getPhaseName(phase); std::string phaseBeginPrefix = "BEGIN_"; std::string phaseEndPrefix = "END_"; - if (phaseName.find(phaseBeginPrefix) != std::string::npos) + if (phase == END_REQ || phase == END_RESP || phase >= END_PDNA) { - phaseName.erase(0, phaseBeginPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].insertPhase(phaseName, time); + phaseName.erase(0, phaseEndPrefix.length()); + currentTransactionsInSystem[&trans].setPhaseEnd(phaseName, time); } else { - phaseName.erase(0, phaseEndPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].setPhaseEnd(phaseName, time); + phaseName.erase(0, phaseBeginPrefix.length()); + currentTransactionsInSystem[&trans].insertPhase(phaseName, time); } if (currentTransactionsInSystem[&trans].cmd == 'X') { - if (std::count(transactionTerminatingPhases.begin(), transactionTerminatingPhases.end(), phase) == 1) + if (phase == END_REFA || phase == END_REFB || phase == END_REFSB + || phase == END_PDNA || phase == END_PDNP || phase == END_SREF) removeTransactionFromSystem(trans); } else @@ -181,14 +183,6 @@ void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans) PRINTDEBUGMESSAGE(name, "New transaction #" + std::to_string(totalNumTransactions) + " generation time " + currentTransactionsInSystem[&trans].timeOfGeneration.to_string()); - - if (totalNumTransactions % transactionCommitRate == 0) - { - PRINTDEBUGMESSAGE(name, "Committing transactions " + - std::to_string(totalNumTransactions - transactionCommitRate + 1) - + " - " + std::to_string(totalNumTransactions)); - commitRecordedDataToDB(); - } } void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans) @@ -199,8 +193,20 @@ void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans) std::to_string(currentTransactionsInSystem[&trans].id)); Transaction &recordingData = currentTransactionsInSystem[&trans]; - recordedData.push_back(recordingData); + currentDataBuffer->push_back(recordingData); currentTransactionsInSystem.erase(&trans); + + if (currentDataBuffer->size() == transactionCommitRate) + { + if (storageThread.joinable()) + storageThread.join(); + + std::swap(currentDataBuffer, storageDataBuffer); + + storageThread = std::thread(&TlmRecorder::commitRecordedDataToDB, this); + currentDataBuffer->clear(); + } + } void TlmRecorder::terminateRemainingTransactions() @@ -228,7 +234,7 @@ void TlmRecorder::terminateRemainingTransactions() void TlmRecorder::commitRecordedDataToDB() { sqlite3_exec(db, "BEGIN;", nullptr, nullptr, nullptr); - for (Transaction &recordingData : recordedData) + for (Transaction &recordingData : *storageDataBuffer) { assert(!recordingData.recordedPhases.empty()); insertTransactionInDB(recordingData); @@ -248,7 +254,6 @@ void TlmRecorder::commitRecordedDataToDB() } sqlite3_exec(db, "COMMIT;", nullptr, nullptr, nullptr); - recordedData.clear(); } @@ -293,55 +298,36 @@ void TlmRecorder::openDB(const std::string &dbName) } } -void TlmRecorder::setUpTransactionTerminatingPhases() -{ - transactionTerminatingPhases.emplace_back(END_RESP); - - // Refresh All - transactionTerminatingPhases.push_back(END_REFA); - - // Refresh Bank - transactionTerminatingPhases.push_back(END_REFB); - - // Refresh Same Bank - transactionTerminatingPhases.push_back(END_REFSB); - - // Phases for Power Down - transactionTerminatingPhases.push_back(END_PDNA); - transactionTerminatingPhases.push_back(END_PDNP); - transactionTerminatingPhases.push_back(END_SREF); -} - void TlmRecorder::prepareSqlStatements() { insertTransactionString = - "INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:rank," - ":bankgroup,:bank,:row,:column,:dataStrobeBegin,:dataStrobeEnd, :timeOfGeneration,:command)"; - + "INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:rank," + ":bankgroup,:bank,:row,:column,:dataStrobeBegin,:dataStrobeEnd, :timeOfGeneration,:command)"; + insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)"; updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id"; updateDataStrobeString = - "UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id"; + "UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id"; insertPhaseString = - "INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)"; + "INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)"; updatePhaseString = - "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; + "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; insertGeneralInfoString = - "INSERT INTO GeneralInfo VALUES" - "(:numberOfTransactions,:end,:numberOfRanks,:numberOfBankgroups,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec," - ":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread, :maxBufferDepth)"; + "INSERT INTO GeneralInfo VALUES" + "(:numberOfTransactions,:end,:numberOfRanks,:numberOfBankgroups,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec," + ":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread, :maxBufferDepth)"; insertCommandLengthsString = - "INSERT INTO CommandLengths VALUES" - "(:NOP, :RD, :WR, :RDA, :WRA, :ACT, :PRE, :REFB, :PRESB, :REFSB, :PREA, :REFA, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; + "INSERT INTO CommandLengths VALUES" + "(:NOP, :RD, :WR, :RDA, :WRA, :ACT, :PRE, :REFB, :PRESB, :REFSB, :PREA, :REFA, :PDEA, :PDXA, :PDEP, :PDXP, :SREFEN, :SREFEX)"; insertDebugMessageString = - "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; + "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)"; insertBufferDepthString = "INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)"; @@ -384,18 +370,18 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0); else sqlite3_bind_int64(insertGeneralInfoStatement, 11, - static_cast((Configuration::getInstance().memSpec->tCK * - Configuration::getInstance().windowSize).value())); - + static_cast((Configuration::getInstance().memSpec->tCK * + Configuration::getInstance().windowSize).value())); + if ((Configuration::getInstance().refreshMaxPostponed > 0) - || (Configuration::getInstance().refreshMaxPulledin > 0)) + || (Configuration::getInstance().refreshMaxPulledin > 0)) { sqlite3_bind_int(insertGeneralInfoStatement, 12, 1); sqlite3_bind_int(insertGeneralInfoStatement, 13, - static_cast(std::max(Configuration::getInstance().refreshMaxPostponed, - Configuration::getInstance().refreshMaxPulledin))); - } - else + static_cast(std::max(Configuration::getInstance().refreshMaxPostponed, + Configuration::getInstance().refreshMaxPulledin))); + } + else { sqlite3_bind_int(insertGeneralInfoStatement, 12, 0); sqlite3_bind_int(insertGeneralInfoStatement, 13, 0); @@ -490,7 +476,7 @@ void TlmRecorder::executeSqlStatement(sqlite3_stmt *statement) int errorCode = sqlite3_step(statement); if (errorCode != SQLITE_DONE) SC_REPORT_FATAL("Error in TraceRecorder", - (std::string("Could not execute statement. Error code: ") + std::to_string(errorCode)).c_str()); + (std::string("Could not execute statement. Error code: ") + std::to_string(errorCode)).c_str()); sqlite3_reset(statement); } @@ -512,6 +498,9 @@ void TlmRecorder::executeInitialSqlCommand() void TlmRecorder::closeConnection() { terminateRemainingTransactions(); + if (storageThread.joinable()) + storageThread.join(); + std::swap(currentDataBuffer, storageDataBuffer); commitRecordedDataToDB(); insertGeneralInfo(); insertCommandLengths(); diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index deefd36f..d4ee9046 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include "sqlite3.h" @@ -116,7 +117,6 @@ private: static void executeSqlStatement(sqlite3_stmt *statement); void openDB(const std::string &dbName); - void setUpTransactionTerminatingPhases(); void introduceTransactionSystem(tlm::tlm_generic_payload &trans); void removeTransactionFromSystem(tlm::tlm_generic_payload &trans); @@ -131,24 +131,27 @@ private: uint64_t transactionID); void insertDebugMessageInDB(const std::string &message, const sc_time &time); - static constexpr unsigned transactionCommitRate = 1024; - std::vector recordedData; + static constexpr unsigned transactionCommitRate = 8192; + std::array, 2> recordingDataBuffer; + std::vector *currentDataBuffer; + std::vector *storageDataBuffer; + std::thread storageThread; + std::unordered_map currentTransactionsInSystem; uint64_t totalNumTransactions; sc_time simulationTimeCoveredByRecording; - std::vector transactionTerminatingPhases; sqlite3 *db = nullptr; sqlite3_stmt *insertTransactionStatement, *insertRangeStatement, - *updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement, - *insertGeneralInfoStatement, *insertCommandLengthsStatement, - *insertDebugMessageStatement, *updateDataStrobeStatement, - *insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement; + *updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement, + *insertGeneralInfoStatement, *insertCommandLengthsStatement, + *insertDebugMessageStatement, *updateDataStrobeStatement, + *insertPowerStatement, *insertBufferDepthStatement, *insertBandwidthStatement; std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, - updatePhaseString, insertGeneralInfoString, insertCommandLengthsString, - insertDebugMessageString, updateDataStrobeString, insertPowerString, - insertBufferDepthString, insertBandwidthString; + updatePhaseString, insertGeneralInfoString, insertCommandLengthsString, + insertDebugMessageString, updateDataStrobeString, insertPowerString, + insertBufferDepthString, insertBandwidthString; std::string initialCommand = "DROP TABLE IF EXISTS Phases; \n" @@ -265,4 +268,3 @@ private: }; #endif // TLMRECORDER_H - diff --git a/DRAMSys/library/src/controller/Command.h b/DRAMSys/library/src/controller/Command.h index c2676400..db48cd85 100644 --- a/DRAMSys/library/src/controller/Command.h +++ b/DRAMSys/library/src/controller/Command.h @@ -88,24 +88,24 @@ class Command public: enum Type : uint8_t { - NOP, - RD, - WR, - RDA, - WRA, - ACT, - PRE, - REFB, - PRESB, - REFSB, - PREA, - REFA, - PDEA, - PDEP, - SREFEN, - PDXA, - PDXP, - SREFEX + NOP, // 0 + RD, // 1 + WR, // 2 + RDA, // 3 + WRA, // 4 + ACT, // 5 + PRE, // 6 + REFB, // 7 + PRESB, // 8 + REFSB, // 9 + PREA, // 10 + REFA, // 11 + PDEA, // 12 + PDEP, // 13 + SREFEN, // 14 + PDXA, // 15 + PDXP, // 16 + SREFEX // 17 }; private: diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 109309bd..1b6e3e33 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -50,9 +50,11 @@ StlPlayer::StlPlayer(const sc_module_name &name, TraceSetup *setup, bool relative) : TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests), - file(pathToTrace), currentBuffer(&lineContents[0]), parseBuffer(&lineContents[1]), - relative(relative), playerClk(playerClk) + file(pathToTrace), relative(relative), playerClk(playerClk) { + currentBuffer = &lineContents[0]; + parseBuffer = &lineContents[1]; + if (!file.is_open()) SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str()); else