Remove stacked plot from CachePlotWidget
Removed for now; having unary options for num/denominator will give
almost the same result, and reduce UI complexity.
MODIFY
src/cachesim/cacheplotwidget.cpp
src/cachesim/cacheplotwidget.cpp
#include "limits.h"
namespace {
-/**
- * @brief stepifySeries
- * Adds additional points to a QLineSeries, effectively transforming it into a step plot to avoid the default point
- * interpolation of a QLineSeries.
- * We create a new pointsVector, preallocate the known final size and finally exchange the points. This is a lot faster
- * than individually inseting points into the series, which each will trigger events within the QLineSeries.
- */
-void stepifySeries(QLineSeries& series) {
- if (series.count() == 0)
- return;
-
- QVector<QPointF> points;
- points.reserve(series.count() * 2);
-
- points << series.at(0); // No stepping is done for the first point
- for (int i = 1; i < series.count(); i++) {
- const QPointF& stepFrom = series.at(i - 1);
- const QPointF& stepTo = series.at(i);
- QPointF interPoint = stepFrom;
- interPoint.setX(stepTo.x());
- points << interPoint << stepTo;
- }
-
- series.replace(points);
-}
inline QPointF stepPoint(const QPointF& p1, const QPointF& p2) {
return QPointF(p2.x(), p1.y());
}
-/**
- * @brief finishSeries
- * Adds an additional point at x value @p max with an equal value of the last value in the series.
- */
-void finishSeries(QLineSeries& series, const unsigned max) {
- if (series.count() == 0) {
- return;
- }
-
- const QPointF lastPoint = series.at(series.count() - 1);
- if (lastPoint.toPoint().x() != static_cast<long>(max)) {
- series.append(max, lastPoint.y());
- }
-}
-
} // namespace
namespace Ripes {
@@ -75,9 +35,6 @@ CachePlotWidget::CachePlotWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui
setupEnumCombobox(m_ui->num, s_cacheVariableStrings);
setupEnumCombobox(m_ui->den, s_cacheVariableStrings);
- setupEnumCombobox(m_ui->plotType, s_cachePlotTypeStrings);
-
- setupStackedVariablesList();
// Set default ratio plot to be hit rate
setEnumIndex(m_ui->num, Variable::Hits);
@@ -85,7 +42,6 @@ CachePlotWidget::CachePlotWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui
connect(m_ui->num, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CachePlotWidget::variablesChanged);
connect(m_ui->den, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CachePlotWidget::variablesChanged);
- connect(m_ui->stackedVariables, &QListWidget::itemChanged, this, &CachePlotWidget::variablesChanged);
m_ui->rangeMin->setValue(0);
m_ui->rangeMax->setValue(ProcessorHandler::getProcessor()->getCycleCount());
@@ -93,9 +49,6 @@ CachePlotWidget::CachePlotWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui
connect(m_ui->rangeMin, QOverload<int>::of(&QSpinBox::valueChanged), this, &CachePlotWidget::rangeChanged);
connect(m_ui->rangeMax, QOverload<int>::of(&QSpinBox::valueChanged), this, &CachePlotWidget::rangeChanged);
- connect(m_ui->plotType, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
- &CachePlotWidget::plotTypeChanged);
-
const QIcon sizeBreakdownIcon = QIcon(":/icons/info.svg");
m_ui->sizeBreakdownButton->setIcon(sizeBreakdownIcon);
connect(m_ui->sizeBreakdownButton, &QPushButton::clicked, this, &CachePlotWidget::showSizeBreakdown);
@@ -123,7 +76,6 @@ void CachePlotWidget::setCache(std::shared_ptr<CacheSim> cache) {
[=] { m_ui->size->setText(QString::number(m_cache->getCacheSize().bits)); });
// Synchronize widget state
- plotTypeChanged();
variablesChanged();
rangeChanged();
updateHitrate();
@@ -133,15 +85,6 @@ CachePlotWidget::~CachePlotWidget() {
delete m_ui;
}
-void CachePlotWidget::setupStackedVariablesList() {
- for (const auto& iter : s_cacheVariableStrings) {
- auto* stackedVariableItem = new QListWidgetItem(iter.second);
- stackedVariableItem->setData(Qt::UserRole, QVariant::fromValue<Variable>(iter.first));
- stackedVariableItem->setCheckState(Qt::Unchecked);
- m_ui->stackedVariables->addItem(stackedVariableItem);
- }
-}
-
void CachePlotWidget::setupToolbar() {
const QIcon crosshairIcon = QIcon(":/icons/crosshair.svg");
m_crosshairAction = new QAction("Enable plot crosshair", this);
@@ -166,20 +109,6 @@ void CachePlotWidget::setupToolbar() {
connect(m_savePlotAction, &QAction::triggered, this, &CachePlotWidget::savePlot);
}
-void CachePlotWidget::plotTypeChanged() {
- m_plotType = getEnumValue<PlotType>(m_ui->plotType);
-
- if (m_plotType == PlotType::Ratio) {
- m_ui->configWidget->setCurrentWidget(m_ui->ratioConfigPage);
- } else if (m_plotType == PlotType::Stacked) {
- m_ui->configWidget->setCurrentWidget(m_ui->stackedConfigPage);
- } else {
- Q_ASSERT(false);
- }
-
- variablesChanged();
-}
-
void CachePlotWidget::savePlot() {
const QString filename = QFileDialog::getSaveFileName(this, "Save file", "", "Images (*.png)");
if (!filename.isEmpty()) {
@@ -238,33 +167,16 @@ void CachePlotWidget::rangeChanged() {
std::vector<CachePlotWidget::Variable> CachePlotWidget::gatherVariables() const {
std::vector<Variable> variables;
- if (m_plotType == PlotType::Ratio) {
const Variable numerator = getEnumValue<Variable>(m_ui->num);
const Variable denominator = getEnumValue<Variable>(m_ui->den);
variables = {numerator, denominator};
- } else if (m_plotType == PlotType::Stacked) {
- for (int i = 0; i < m_ui->stackedVariables->count(); ++i) {
- QListWidgetItem* item = m_ui->stackedVariables->item(i);
- if (item->checkState() == Qt::Checked) {
- variables.push_back(qvariant_cast<Variable>(item->data(Qt::UserRole)));
- }
- }
- } else {
- Q_ASSERT(false);
- }
return variables;
}
void CachePlotWidget::variablesChanged() {
const auto vars = gatherVariables();
- if (m_plotType == PlotType::Ratio) {
Q_ASSERT(vars.size() == 2);
setPlot(createRatioPlot(vars.at(0), vars.at(1)));
- } else if (m_plotType == PlotType::Stacked) {
- setPlot(createStackedPlot(vars));
- } else {
- Q_ASSERT(false);
- }
}
std::map<CachePlotWidget::Variable, QList<QPoint>> CachePlotWidget::gatherData(unsigned fromCycle) const {
@@ -364,87 +276,6 @@ QChart* CachePlotWidget::createRatioPlot(const Variable num, const Variable den)
return chart;
}
-QChart* CachePlotWidget::createStackedPlot(const std::vector<Variable>& variables) const {
- if (variables.size() == 0) {
- return nullptr;
- }
-
- const auto cacheData = gatherData();
- const unsigned len = cacheData.at(*variables.begin()).size();
- for (const auto& iter : cacheData) {
- Q_ASSERT(static_cast<long>(len) == iter.second.size());
- }
-
- QChart* chart = new QChart();
- chart->setTitle("Access type count");
- QFont font;
- font.setPointSize(16);
- chart->setTitleFont(font);
-
- // The lower series initialized to zero values
-
- // We create a stacked chart by repeatedly creating line series with y values equal to the variable set's y
- // value + the preceding linesets envelope values.
- std::vector<std::pair<Variable, QLineSeries*>> lineSeries;
- QLineSeries* lowerSeries = nullptr;
- QLineSeries* upperSeries = nullptr;
- const unsigned maxX = ProcessorHandler::getProcessor()->getCycleCount();
- unsigned maxY = 0;
- for (const auto& variableData : cacheData) {
- upperSeries = new QLineSeries(chart);
- for (unsigned i = 0; i < len; i++) {
- const auto& dataPoint = variableData.second.at(i);
- unsigned x = dataPoint.x();
- unsigned y = dataPoint.y();
- if (lowerSeries) {
- // Stack on top of the preceding line
- const auto& lowerPoints = lowerSeries->pointsVector();
- y = lowerPoints[i].y() + dataPoint.y();
- }
- maxY = y > maxY ? y : maxY;
- upperSeries->append(QPoint(x, y));
- }
- lineSeries.push_back({variableData.first, upperSeries});
- lowerSeries = upperSeries;
- }
-
- // Stepify created lineseries
- std::map<Variable, QVector<QPointF>> debug;
- for (const auto& line : lineSeries) {
- debug[line.first] = line.second->pointsVector();
- }
- for (const auto& line : lineSeries) {
- stepifySeries(*line.second);
- finishSeries(*line.second, maxX);
- debug[line.first] = line.second->pointsVector();
- }
-
- // Create area series
- lowerSeries = nullptr;
- for (unsigned i = 0; i < lineSeries.size(); i++) {
- upperSeries = lineSeries[i].second;
- QAreaSeries* area = new QAreaSeries(upperSeries, lowerSeries);
- area->setName(s_cacheVariableStrings.at(lineSeries[i].first));
- chart->addSeries(area);
- lowerSeries = upperSeries;
- }
-
- chart->createDefaultAxes();
-
- // Add space to label to add space between labels and axis
- QValueAxis* axisY = qobject_cast<QValueAxis*>(chart->axes(Qt::Vertical).first());
- QValueAxis* axisX = qobject_cast<QValueAxis*>(chart->axes(Qt::Horizontal).first());
- axisX->setRange(0, maxX);
- axisY->setRange(0, axisY->max());
-
- Q_ASSERT(axisY);
- axisY->setTitleText("#");
- axisX->setTitleText("Cycle");
- axisX->setLabelFormat("%d ");
-
- return chart;
-}
-
void CachePlotWidget::setPlot(QChart* plot) {
if (plot == nullptr)
return;

MODIFY
src/cachesim/cacheplotwidget.h
src/cachesim/cacheplotwidget.h
@@ -28,7 +28,6 @@ class CachePlotWidget : public QWidget {
public:
enum Variable { Writes = 0, Reads, Hits, Misses, Writebacks, Accesses, N_Variables };
- enum class PlotType { Ratio, Stacked };
explicit CachePlotWidget(QWidget* parent = nullptr);
void setCache(std::shared_ptr<CacheSim> cache);
~CachePlotWidget();
@@ -38,7 +37,6 @@ public slots:
private slots:
void variablesChanged();
void rangeChanged();
- void plotTypeChanged();
void updateHitrate();
private:
@@ -49,7 +47,6 @@ private:
*/
std::map<Variable, QList<QPoint>> gatherData(unsigned fromCycle = 0) const;
void setupToolbar();
- void setupStackedVariablesList();
void showSizeBreakdown();
void setPlot(QChart* plot);
void copyPlotDataToClipboard() const;
@@ -58,9 +55,6 @@ private:
void updateRatioPlot(QLineSeries* series, const Variable num, const Variable den);
QChart* createRatioPlot(const Variable num, const Variable den);
- QChart* createStackedPlot(const std::vector<Variable>& variables) const;
-
- PlotType m_plotType = PlotType::Ratio;
QChart* m_currentPlot = nullptr;
Ui::CachePlotWidget* m_ui;
@@ -80,11 +74,6 @@ const static std::map<CachePlotWidget::Variable, QString> s_cacheVariableStrings
{CachePlotWidget::Variable::Writebacks, "Writebacks"},
{CachePlotWidget::Variable::Accesses, "Total accesses"}};
-const static std::map<CachePlotWidget::PlotType, QString> s_cachePlotTypeStrings{
- {CachePlotWidget::PlotType::Ratio, "Ratio"},
- {CachePlotWidget::PlotType::Stacked, "Stacked"}};
-
} // namespace Ripes
Q_DECLARE_METATYPE(Ripes::CachePlotWidget::Variable);
-Q_DECLARE_METATYPE(Ripes::CachePlotWidget::PlotType);

MODIFY
src/cachesim/cacheplotwidget.ui
src/cachesim/cacheplotwidget.ui
<rect>
<x>0</x>
<y>0</y>
- <width>617</width>
+ <width>714</width>
<height>330</height>
</rect>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <layout class="QGridLayout" name="gridLayout_3">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Plot configuration:</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
- <widget class="QLabel" name="label_3">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_2">
<property name="text">
- <string>Plot type</string>
+ <string>Denominator</string>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="rangeMin">
- <property name="maximum">
- <number>999999999</number>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Numerator</string>
</property>
</widget>
</item>
- <item row="1" column="0">
+ <item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Cycles min.</string>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QComboBox" name="plotType"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Cycles max.</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
+ <item row="1" column="1">
<widget class="QSpinBox" name="rangeMax">
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
- </layout>
- </item>
- <item>
- <widget class="QScrollArea" name="scrollArea">
- <property name="widgetResizable">
- <bool>true</bool>
- </property>
- <widget class="QWidget" name="scrollAreaWidgetContents_2">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>221</width>
- <height>214</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QStackedWidget" name="configWidget">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <widget class="QWidget" name="stackedConfigPage">
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="0" column="0">
- <widget class="QListWidget" name="stackedVariables"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="ratioConfigPage">
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="0" column="0">
- <layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="1">
- <widget class="QComboBox" name="num"/>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Numerator</string>
+ <widget class="QSpinBox" name="rangeMin">
+ <property name="maximum">
+ <number>999999999</number>
</property>
</widget>
</item>
<item row="1" column="0">
- <widget class="QLabel" name="label_2">
+ <widget class="QLabel" name="label_7">
<property name="text">
- <string>Denominator</string>
+ <string>Cycles max.</string>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QComboBox" name="den"/>
- </item>
- </layout>
+ <item row="0" column="3">
+ <widget class="QComboBox" name="num"/>
</item>
- <item row="1" column="0">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
+ <item row="1" column="3">
+ <widget class="QComboBox" name="den"/>
</item>
</layout>
- </widget>
- </widget>
</item>
</layout>
</widget>
- </widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">

Remove stacked plot from CachePlotWidget

Removed for now; having unary options for num/denominator will give
almost the same result, and reduce UI complexity.