Implement a maximum for # of cache access cycles to plot
MODIFY
src/cachesim/cacheplotwidget.cpp
src/cachesim/cacheplotwidget.cpp
@@ -62,6 +62,15 @@ CachePlotWidget::CachePlotWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui
connect(m_ui->sizeBreakdownButton, &QPushButton::clicked, this, &CachePlotWidget::showSizeBreakdown);
connect(m_ui->windowed, &QCheckBox::toggled, m_ui->windowCycles, &QWidget::setEnabled);
connect(m_ui->windowed, &QCheckBox::toggled, m_ui->mavgCursor, &QWidget::setEnabled);
+
+ connect(m_ui->maxCyclesButton, &QPushButton::clicked, this, [=] {
+ QMessageBox::information(
+ this, "Maximum plot cycles reached",
+ "The maximum number of plot cycles was reached. Beyond this point, cache statistics is no longer plotted "
+ "for performance reasons.\nIf you wish to increase the # of cycles plotted, please change the setting:\n "
+ " "
+ "\"Edit->Settings->Environment->Max. cache plot cycles\"");
+ });
}
void CachePlotWidget::showSizeBreakdown() {
@@ -86,15 +95,24 @@ void CachePlotWidget::setCache(std::shared_ptr<CacheSim> cache) {
[=] { m_ui->size->setText(QString::number(m_cache->getCacheSize().bits)); });
m_ui->size->setText(QString::number(m_cache->getCacheSize().bits));
- connect(ProcessorHandler::get(), &ProcessorHandler::processorClockedNonRun, [=] {
+ const auto plotUpdateFunc = [=]() {
+ if (m_lastCyclePlotted >= RipesSettings::value(RIPES_SETTING_CACHE_MAXCYCLES).toUInt()) {
+ return false;
+ }
updateAllowedRange(RangeChangeSource::Cycles);
+ return true;
+ };
+ connect(ProcessorHandler::get(), &ProcessorHandler::processorClockedNonRun, this, [=] {
+ if (plotUpdateFunc()) {
updateRatioPlot();
+ }
});
- connect(ProcessorHandler::get(), &ProcessorHandler::runFinished, [=] {
- updateAllowedRange(RangeChangeSource::Cycles);
+ connect(ProcessorHandler::get(), &ProcessorHandler::runFinished, this, [=] {
+ if (plotUpdateFunc()) {
updateRatioPlot();
+ }
});
- connect(m_cache.get(), &CacheSim::cacheInvalidated, [=] {
+ connect(m_cache.get(), &CacheSim::cacheInvalidated, this, [=] {
updateAllowedRange(RangeChangeSource::Cycles);
resetRatioPlot();
});
@@ -119,6 +137,7 @@ void CachePlotWidget::setCache(std::shared_ptr<CacheSim> cache) {
variablesChanged();
rangeChanged(RangeChangeSource::Comboboxes);
updateHitrate();
+ updatePlotWarningButton();
}
void CachePlotWidget::updateAllowedRange(const RangeChangeSource src) {
@@ -128,7 +147,9 @@ void CachePlotWidget::updateAllowedRange(const RangeChangeSource src) {
}
// Update allowed ranges
- const unsigned cycles = ProcessorHandler::getProcessor()->getCycleCount();
+ unsigned cycles = ProcessorHandler::getProcessor()->getCycleCount();
+ const unsigned maxCycles = RipesSettings::value(RIPES_SETTING_CACHE_MAXCYCLES).toUInt();
+ cycles = cycles > maxCycles ? maxCycles : cycles;
bool atMax = false;
@@ -268,9 +289,20 @@ std::map<CachePlotWidget::Variable, QList<QPoint>> CachePlotWidget::gatherData(u
cacheData[static_cast<Variable>(i)].reserve(trace.size());
}
- // Gather data
+ // Gather data up until the end of the trace or the maximum plotted cycles
- for (auto it = trace.upper_bound(fromCycle); it != trace.end(); it++) {
+ unsigned cycles = ProcessorHandler::getProcessor()->getCycleCount();
+ const unsigned maxCycles = RipesSettings::value(RIPES_SETTING_CACHE_MAXCYCLES).toUInt();
+ cycles = cycles > maxCycles ? maxCycles : cycles;
+
+ decltype(trace.begin()) traceEndIt;
+ if (trace.size() > maxCycles) {
+ traceEndIt = trace.upper_bound(maxCycles);
+ } else {
+ traceEndIt = trace.end();
+ }
+
+ for (auto it = trace.upper_bound(fromCycle); it != traceEndIt; it++) {
const auto& entry = it->second;
cacheData[Variable::Writes].append(QPoint(it->first, entry.writes));
cacheData[Variable::Reads].append(QPoint(it->first, entry.reads));
@@ -339,8 +371,8 @@ void CachePlotWidget::updateRatioPlot() {
lastPoint = QPointF(-1, 0);
}
for (int i = 0; i < nNewPoints; i++) {
- // Cummulative plot. For the unary variable, "Accesses" is just used to index into the cache data for accessing
- // the x variable.
+ // Cummulative plot. For the unary variable, "Accesses" is just used to index into the cache data for
+ // accessing the x variable.
const auto& p1 =
m_numerator == Unary ? QPoint(newCacheData.at(Accesses).at(i).x(), 1) : newCacheData.at(m_numerator).at(i);
const auto& p2 = m_denominator == Unary ? QPoint(newCacheData.at(Accesses).at(i).x(), 1)
@@ -446,6 +478,13 @@ void CachePlotWidget::updateRatioPlot() {
axisY->setRange(m_minY, axisMaxY);
axisX->setRange(m_ui->rangeSlider->minimumPosition(), m_ui->rangeSlider->maximumPosition());
+
+ updatePlotWarningButton();
+}
+
+void CachePlotWidget::updatePlotWarningButton() {
+ m_ui->maxCyclesButton->setVisible(m_lastCyclePlotted >=
+ RipesSettings::value(RIPES_SETTING_CACHE_MAXCYCLES).toUInt());
}
void CachePlotWidget::resetRatioPlot() {
@@ -469,6 +508,7 @@ void CachePlotWidget::resetRatioPlot() {
}
updateRatioPlot();
+ updatePlotWarningButton();
}
void CachePlotWidget::updateHitrate() {

MODIFY
src/cachesim/cacheplotwidget.h
src/cachesim/cacheplotwidget.h
@@ -71,6 +71,7 @@ private:
void savePlot();
void updateRatioPlot();
void updateAllowedRange(const RangeChangeSource src);
+ void updatePlotWarningButton();
/**
* @brief resampleToScreen

MODIFY
src/cachesim/cacheplotwidget.ui
src/cachesim/cacheplotwidget.ui
<number>0</number>
</property>
<item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,0,0">
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1,0,0">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
</item>
</layout>
</item>
+ <item>
+ <widget class="QPushButton" name="maxCyclesButton">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Maximum cache plot cycles reached! Click for info...</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="CachePlotView" name="plotView"/>
</item>

MODIFY
src/cachesim/cachesim.cpp
src/cachesim/cachesim.cpp
@@ -27,7 +27,6 @@ CacheSim::CacheSim(QObject* parent) : CacheInterface(parent) {
// Given that we are not updating the graphical state of the cache simulator whilst the processor is running,
// once running is finished, the entirety of the cache view should be reloaded in the graphical view.
emit hitrateChanged();
- emit cacheInvalidated();
});
updateConfiguration();

MODIFY
src/ripessettings.cpp
src/ripessettings.cpp
@@ -26,6 +26,7 @@ const std::map<QString, QVariant> s_defaultSettings = {
{RIPES_SETTING_ASSEMBLER_BSSSTART, 0x11000000},
{RIPES_SETTING_PERIPHERALS_START, static_cast<unsigned>(0xF0000000)},
+ {RIPES_SETTING_CACHE_MAXCYCLES, 10000},
{RIPES_SETTING_CACHE_MAXPOINTS, 1000},
{RIPES_SETTING_CACHE_PRESETS,
QVariant::fromValue<QList<CachePreset>>(

MODIFY
src/ripessettings.h
src/ripessettings.h
@@ -23,6 +23,7 @@ namespace Ripes {
#define RIPES_SETTING_ASSEMBLER_BSSSTART ("bss_start")
#define RIPES_SETTING_PERIPHERALS_START ("peripheral_start")
+#define RIPES_SETTING_CACHE_MAXCYCLES ("cacheplot_maxcycles")
#define RIPES_SETTING_CACHE_MAXPOINTS ("cacheplot_maxpoints")
#define RIPES_SETTING_CACHE_PRESETS ("cache_presets")
#define RIPES_SETTING_PERIPHERAL_SETTINGS ("peripheral_settings")

MODIFY
src/settingsdialog.cpp
src/settingsdialog.cpp
@@ -288,8 +288,18 @@ QWidget* SettingsDialog::createEditorPage() {
QWidget* SettingsDialog::createEnvironmentPage() {
auto [pageWidget, pageLayout] = constructPage();
+ auto [maxcyclesLabel, maxcyclesSb] =
+ createSettingsWidgets<QSpinBox>(RIPES_SETTING_CACHE_MAXCYCLES, "Max. cache plot cycles");
+ maxcyclesSb->setMinimum(0);
+ appendToLayout({maxcyclesLabel, maxcyclesSb}, pageLayout,
+ "Maximum number of cache cycles to plot. Increasing this may incur substantial slowdown for long "
+ "time executing programs, given the number of points to be plotted.");
+
+ auto [maxPointsLabel, maxPointsSb] =
+ createSettingsWidgets<QSpinBox>(RIPES_SETTING_CACHE_MAXPOINTS, "Min. cache plot points:");
+ maxPointsSb->setMinimum(2);
appendToLayout(
- createSettingsWidgets<QSpinBox>(RIPES_SETTING_CACHE_MAXPOINTS, "Min. cache plot points:"), pageLayout,
+ {maxPointsLabel, maxPointsSb}, pageLayout,
"Minimum number of points to be kept in the cache plot. Once 2x this amount is reached, the cache "
"plot will be resampled to this minimum value, and new points will be added based on the sampling "
"rate after the resampling. This resampling allows for real-time plotting regardless of the number of "

Implement a maximum for # of cache access cycles to plot