From c744c43ab264ef4f545b9f8916d0a010ec49b4f7 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Tue, 27 Oct 2020 21:29:39 +0100 Subject: [PATCH] Added first latency analysis --- .../resources/configs/simulator/ddr3.json | 4 +- DRAMSys/traceAnalyzer/data/tracedb.cpp | 5 + DRAMSys/traceAnalyzer/data/tracedb.h | 2 + DRAMSys/traceAnalyzer/scripts/plots.py | 39 +++++++ DRAMSys/traceAnalyzer/tracefiletab.cpp | 88 ++++++++++++++- DRAMSys/traceAnalyzer/tracefiletab.h | 3 + DRAMSys/traceAnalyzer/tracefiletab.ui | 102 ++++++++++++------ 7 files changed, 210 insertions(+), 33 deletions(-) diff --git a/DRAMSys/library/resources/configs/simulator/ddr3.json b/DRAMSys/library/resources/configs/simulator/ddr3.json index 99ccdb45..3f8bf627 100644 --- a/DRAMSys/library/resources/configs/simulator/ddr3.json +++ b/DRAMSys/library/resources/configs/simulator/ddr3.json @@ -5,10 +5,10 @@ "DatabaseRecording": true, "Debug": false, "ECCControllerMode": "Disabled", - "EnableWindowing": false, + "EnableWindowing": true, "ErrorCSVFile": "", "ErrorChipSeed": 42, - "PowerAnalysis": false, + "PowerAnalysis": true, "SimulationName": "ddr3", "SimulationProgressBar": true, "StoreMode": "NoStorage", diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index d8f177ca..8e80d978 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -348,6 +348,11 @@ vector TraceDB::getDebugMessagesInTimespan(const Timespan &span, return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit); } +QSqlDatabase TraceDB::getDatabase() const +{ + return database; +} + /* Helpers * * diff --git a/DRAMSys/traceAnalyzer/data/tracedb.h b/DRAMSys/traceAnalyzer/data/tracedb.h index 57a87055..d4c185a0 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.h +++ b/DRAMSys/traceAnalyzer/data/tracedb.h @@ -102,6 +102,8 @@ public: std::vector getDebugMessagesInTimespan(const Timespan &span, unsigned int limit); + QSqlDatabase getDatabase() const; + private: QString pathToDB; QSqlDatabase database; diff --git a/DRAMSys/traceAnalyzer/scripts/plots.py b/DRAMSys/traceAnalyzer/scripts/plots.py index aefb1235..990ba912 100755 --- a/DRAMSys/traceAnalyzer/scripts/plots.py +++ b/DRAMSys/traceAnalyzer/scripts/plots.py @@ -252,6 +252,45 @@ def power_window(connection, tracePath, steps): return outputFile +@plot +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): diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index ca88744c..3acbf409 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -41,6 +41,9 @@ #include "QFileInfo" #include "qmessagebox.h" #include +#include +#include +#include TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) : QWidget(parent), ui(new Ui::TraceFileTab), savingChangesToDB(false) @@ -82,7 +85,6 @@ void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path) ui->selectedTransactionTree->init(navigator); //ui->debugMessages->init(navigator,ui->traceplot); ui->commentTree->init(navigator); - } void TraceFileTab::setUpFileWatcher(QString path) @@ -110,3 +112,87 @@ void TraceFileTab::tracefileChanged() navigator->refreshData(); } +class ItemDelegate: public QItemDelegate +{ +public: + ItemDelegate(QObject* parent = nullptr): QItemDelegate(parent) + { + } + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const + { + if (index.column() == 1) { + double progress = index.data().toDouble(); + QStyleOptionProgressBar opt; + opt.rect = option.rect; + opt.minimum = 0; + opt.maximum = 100; + opt.progress = static_cast(progress); + opt.text = QString::number(progress, 'f', 2)+" %"; + opt.textVisible = true; + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, nullptr); + } else { + QItemDelegate::paint(painter, option, index); + } + } +}; + +void TraceFileTab::on_tabWidget_currentChanged(int index) +{ + if(index == 1) // Changed to latency tab: + { + // Create Database Setup and Query: + QString sql = "SELECT ((p2.PhaseEnd - p1.PhaseBegin)/1000) as latency, 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\" ORDER BY latency;"; + + QSqlDatabase db = navigator->TraceFile().getDatabase(); + QSqlQuery query(db); + query.exec(sql); + + // Creatoe model and fill it from Database: + QStandardItemModel* model = new QStandardItemModel(); + + int currentLatency = 0; + QStandardItem* currentLatencyItem = nullptr; + int counter = 0; + while (query.next()) { + if(query.value(0) != currentLatency) { + currentLatencyItem = new QStandardItem(QString::number(query.value(0).toInt())+" ns"); + currentLatency = query.value(0).toInt(); + QList row; + row.append(currentLatencyItem); + row.append(new QStandardItem()); + model->appendRow(row); + } + QStandardItem * id = new QStandardItem(query.value(1).toString()); + currentLatencyItem->appendRow(id); + counter++; + } + QStringList header = {"Latency","Occurences"}; + model->setHorizontalHeaderLabels(header); + + // Generate Histrogram: + for(int i = 0; i < model->rowCount(); i++) { + int numberOfChilds = model->item(i)->rowCount(); + double percentage = 100*((double(numberOfChilds))/(double(counter))); + model->item(i,1)->setText(QString::number(percentage)); + } + ui->latencyTreeView->setItemDelegate(new ItemDelegate(ui->latencyTreeView)); + ui->latencyTreeView->setModel(model); + } +} + +void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex &index) +{ + // Get onlye the leaf: + if(index.column() == 0 && index.model()->hasChildren(index) == false) { + unsigned int id = index.data().toUInt(); + if(id!=0) { + navigator->selectTransaction(id); + } + } +} diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index ddc912cc..a802e5b8 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -79,6 +79,9 @@ public Q_SLOTS: Q_SIGNALS: void statusChanged(QString message, bool saveChangesEnable = false); void colorGroupingChanged(ColorGrouping colorgrouping); +private Q_SLOTS: + void on_tabWidget_currentChanged(int index); + void on_latencyTreeView_doubleClicked(const QModelIndex &index); }; #endif // TRACEFILETAB_H diff --git a/DRAMSys/traceAnalyzer/tracefiletab.ui b/DRAMSys/traceAnalyzer/tracefiletab.ui index d6951f1b..77e62437 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.ui +++ b/DRAMSys/traceAnalyzer/tracefiletab.ui @@ -58,46 +58,88 @@ - - - - 3 - 3 - - + - 300 - 0 + 0 + 500 - - - 16777215 - 16777215 - - - - true - - - false - - - false - - + 0 - - true - + + + Selected Transaction + + + + + + + + + 3 + 3 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + true + + + false + + + false + + + 0 + + + true + + + + + + + + + + Latency Analysis + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + - + 2 1 @@ -105,7 +147,7 @@ 300 - 0 + 200