Skip to content

Commit 2c575a9

Browse files
authored
GUI: Performance optimizations (#162)
2 parents cb8fa05 + 715275e commit 2c575a9

File tree

15 files changed

+206
-101
lines changed

15 files changed

+206
-101
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ if (NOT "${BUILD_DEBUG}")
132132
add_definitions(-DQT_NO_DEBUG_OUTPUT=1)
133133
endif ()
134134

135+
add_compile_definitions(QT_USE_QSTRINGBUILDER)
136+
137+
# Profiling flags
138+
if (NOT "${WASM}" AND NOT "${WIN32}")
139+
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
140+
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
141+
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
142+
endif ()
143+
135144
include_directories("src" "src/machine")
136145

137146

src/gui/windows/cache/cachedock.cpp

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,25 @@ CacheDock::CacheDock(QWidget *parent, const QString &type)
1212
layout_top_form = new QFormLayout(top_form);
1313

1414
l_hit = new QLabel("0", top_form);
15+
l_hit->setTextFormat(Qt::PlainText);
1516
layout_top_form->addRow("Hit:", l_hit);
1617
l_miss = new QLabel("0", top_form);
18+
l_miss->setTextFormat(Qt::PlainText);
1719
layout_top_form->addRow("Miss:", l_miss);
1820
l_m_reads = new QLabel("0", top_form);
21+
l_m_reads->setTextFormat(Qt::PlainText);
1922
layout_top_form->addRow("Memory reads:", l_m_reads);
2023
l_m_writes = new QLabel("0", top_form);
24+
l_m_writes->setTextFormat(Qt::PlainText);
2125
layout_top_form->addRow("Memory writes:", l_m_writes);
2226
l_stalled = new QLabel("0", top_form);
27+
l_stalled->setTextFormat(Qt::PlainText);
2328
layout_top_form->addRow("Memory stall cycles:", l_stalled);
2429
l_hit_rate = new QLabel("0.000%", top_form);
30+
l_hit_rate->setTextFormat(Qt::PlainText);
2531
layout_top_form->addRow("Hit rate:", l_hit_rate);
2632
l_speed = new QLabel("100%", top_form);
33+
l_speed->setTextFormat(Qt::PlainText);
2734
layout_top_form->addRow("Improved speed:", l_speed);
2835

2936
graphicsview = new GraphicsView(top_widget);
@@ -39,6 +46,14 @@ CacheDock::CacheDock(QWidget *parent, const QString &type)
3946
}
4047

4148
void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
49+
memory_reads = 0;
50+
memory_writes = 0;
51+
hit = 0;
52+
miss = 0;
53+
stalled = 0;
54+
speed_improv = 0.0;
55+
hit_rate = 0.0;
56+
4257
l_hit->setText("0");
4358
l_miss->setText("0");
4459
l_stalled->setText("0");
@@ -48,19 +63,12 @@ void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
4863
l_speed->setText("100%");
4964
l_speed->setHidden(cache_after_cache);
5065
if (cache != nullptr) {
66+
connect(cache, &machine::Cache::hit_update, this, &CacheDock::hit_update);
67+
connect(cache, &machine::Cache::miss_update, this, &CacheDock::miss_update);
68+
connect(cache, &machine::Cache::memory_reads_update, this, &CacheDock::memory_reads_update);
5169
connect(
52-
cache, &machine::Cache::hit_update, this, &CacheDock::hit_update);
53-
connect(
54-
cache, &machine::Cache::miss_update, this, &CacheDock::miss_update);
55-
connect(
56-
cache, &machine::Cache::memory_reads_update, this,
57-
&CacheDock::memory_reads_update);
58-
connect(
59-
cache, &machine::Cache::memory_writes_update, this,
60-
&CacheDock::memory_writes_update);
61-
connect(
62-
cache, &machine::Cache::statistics_update, this,
63-
&CacheDock::statistics_update);
70+
cache, &machine::Cache::memory_writes_update, this, &CacheDock::memory_writes_update);
71+
connect(cache, &machine::Cache::statistics_update, this, &CacheDock::statistics_update);
6472
}
6573
top_form->setVisible(cache != nullptr);
6674
no_cache->setVisible(cache == nullptr || !cache->get_config().enabled());
@@ -71,27 +79,38 @@ void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
7179
graphicsview->setVisible(cache != nullptr && cache->get_config().enabled());
7280
}
7381

82+
void CacheDock::paintEvent(QPaintEvent *event) {
83+
l_stalled->setText(QString::number(stalled));
84+
l_hit_rate->setText(QString::number(hit_rate, 'f', 3) + QString("%"));
85+
l_speed->setText(QString::number(speed_improv, 'f', 0) + QString("%"));
86+
l_hit->setText(QString::number(hit));
87+
l_miss->setText(QString::number(miss));
88+
l_m_reads->setText(QString::number(memory_reads));
89+
l_m_writes->setText(QString::number(memory_writes));
90+
QDockWidget::paintEvent(event);
91+
}
92+
7493
void CacheDock::hit_update(unsigned val) {
75-
l_hit->setText(QString::number(val));
94+
hit = val;
7695
}
7796

7897
void CacheDock::miss_update(unsigned val) {
79-
l_miss->setText(QString::number(val));
98+
miss = val;
8099
}
81100

82101
void CacheDock::memory_reads_update(unsigned val) {
83-
l_m_reads->setText(QString::number(val));
102+
memory_reads = val;
84103
}
85104

86105
void CacheDock::memory_writes_update(unsigned val) {
87-
l_m_writes->setText(QString::number(val));
106+
memory_writes = val;
88107
}
89108

90109
void CacheDock::statistics_update(
91110
unsigned stalled_cycles,
92111
double speed_improv,
93112
double hit_rate) {
94-
l_stalled->setText(QString::number(stalled_cycles));
95-
l_hit_rate->setText(QString::number(hit_rate, 'f', 3) + QString("%"));
96-
l_speed->setText(QString::number(speed_improv, 'f', 0) + QString("%"));
113+
this->stalled = stalled_cycles;
114+
this->hit = hit_rate;
115+
this->speed_improv = speed_improv;
97116
}

src/gui/windows/cache/cachedock.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class CacheDock : public QDockWidget {
1616

1717
void setup(const machine::Cache *cache, bool cache_after_cache = false);
1818

19+
void paintEvent(QPaintEvent *event) override;
20+
1921
private slots:
2022
void hit_update(unsigned);
2123
void miss_update(unsigned);
@@ -35,6 +37,15 @@ private slots:
3537
QLabel *l_m_reads, *l_m_writes;
3638
GraphicsView *graphicsview;
3739
CacheViewScene *cachescene;
40+
41+
// Statistics
42+
unsigned memory_reads = 0;
43+
unsigned memory_writes = 0;
44+
unsigned hit = 0;
45+
unsigned miss = 0;
46+
unsigned stalled = 0;
47+
double speed_improv = 0.0;
48+
double hit_rate = 0.0;
3849
};
3950

4051
#endif // CACHEDOCK_H

src/gui/windows/cache/cacheview.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
#include "fontsize.h"
44

5-
#include <cmath>
6-
75
#include <QtAlgorithms>
6+
#include <cmath>
87

98
//////////////////////
109
#define ROW_HEIGHT 14
@@ -27,9 +26,13 @@ static inline unsigned int bitsToRepresent(quint32 range_max_val) {
2726
CacheAddressBlock::CacheAddressBlock(const machine::Cache *cache, unsigned width) {
2827
rows = cache->get_config().set_count();
2928
columns = cache->get_config().block_size();
30-
s_row = cache->get_config().set_count() > 1 ? bitsToRepresent(cache->get_config().set_count() - 1) : 0;
29+
s_row = cache->get_config().set_count() > 1
30+
? bitsToRepresent(cache->get_config().set_count() - 1)
31+
: 0;
3132
this->width = width;
32-
s_col = cache->get_config().block_size() > 1 ? bitsToRepresent(cache->get_config().block_size() - 1) : 0;
33+
s_col = cache->get_config().block_size() > 1
34+
? bitsToRepresent(cache->get_config().block_size() - 1)
35+
: 0;
3336
s_tag = 30 - s_row - s_col; // 32 bits - 2 unused and then every bit used
3437
// for different index
3538
this->width = width;
@@ -353,14 +356,15 @@ void CacheViewBlock::cache_update(
353356
validity[set]->setText(valid ? "1" : "0");
354357
if (this->dirty) { this->dirty[set]->setText(valid ? (dirty ? "1" : "0") : ""); }
355358
// TODO calculate correct size of tag
356-
this->tag[set]->setText(valid ? QString("0x") + QString("%1").arg(tag, 8, 16, QChar('0')) : "");
359+
this->tag[set]->setText(
360+
valid ? QString("0x") + QString("%1").arg(tag, 8, 16, QChar('0')) : QString(""));
357361
for (unsigned i = 0; i < columns; i++) {
358362
this->data[set][i]->setText(
359363
valid ? QString("0x")
360364
+ QString("%1").arg(
361365
byteswap_if(data[i], simulated_machine_endian != NATIVE_ENDIAN), 8, 16,
362366
QChar('0'))
363-
: "");
367+
: QString(""));
364368
// TODO Use cache API
365369
}
366370

src/gui/windows/csr/csrdock.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22

33
#include "csr/controlstate.h"
44

5-
CsrDock::CsrDock(QWidget *parent) : QDockWidget(parent) {
5+
CsrDock::CsrDock(QWidget *parent)
6+
: QDockWidget(parent)
7+
, xlen(machine::Xlen::_32)
8+
, csr_handle(nullptr) {
69
scrollarea = new QScrollArea(this);
710
scrollarea->setWidgetResizable(true);
811
widg = new StaticTable(scrollarea);
9-
xlen = machine::Xlen::_32;
1012

1113
for (size_t i = 0; i < machine::CSR::REGISTERS.size(); i++) {
1214
auto &desc = machine::CSR::REGISTERS.at(i);
1315
csr_view[i] = new QLabel(sizeHintText(), widg);
16+
csr_view[i]->setTextFormat(Qt::PlainText);
1417
csr_view[i]->setFixedSize(csr_view[i]->sizeHint());
1518
csr_view[i]->setText("");
1619
csr_view[i]->setTextInteractionFlags(Qt::TextSelectableByMouse);
@@ -34,14 +37,6 @@ CsrDock::CsrDock(QWidget *parent) : QDockWidget(parent) {
3437
pal_read.setColor(QPalette::WindowText, QColor(0, 0, 240));
3538
csr_highlighted_any = false;
3639
}
37-
38-
const char *CsrDock::sizeHintText() {
39-
if (xlen == machine::Xlen::_64)
40-
return "0x0000000000000000";
41-
else
42-
return "0x00000000";
43-
}
44-
4540
void CsrDock::setup(machine::Machine *machine) {
4641
if (machine == nullptr) {
4742
// Reset data
@@ -51,10 +46,6 @@ void CsrDock::setup(machine::Machine *machine) {
5146
return;
5247
}
5348

54-
const machine::CSR::ControlState *controlst = machine->control_state();
55-
if (controlst == nullptr)
56-
return;
57-
5849
// if xlen changes adjust space to show full value
5950
if (xlen != machine->config().get_simulated_xlen()) {
6051
xlen = machine->config().get_simulated_xlen();
@@ -65,16 +56,31 @@ void CsrDock::setup(machine::Machine *machine) {
6556
delete dumy_data_label;
6657
}
6758

59+
csr_handle = machine->control_state();
60+
reload();
61+
connect(csr_handle, &machine::CSR::ControlState::write_signal, this, &CsrDock::csr_changed);
62+
connect(csr_handle, &machine::CSR::ControlState::read_signal, this, &CsrDock::csr_read);
63+
connect(machine, &machine::Machine::tick, this, &CsrDock::clear_highlights);
64+
}
65+
66+
const char *CsrDock::sizeHintText() {
67+
if (xlen == machine::Xlen::_64)
68+
return "0x0000000000000000";
69+
else
70+
return "0x00000000";
71+
}
72+
73+
void CsrDock::reload() {
74+
if (csr_handle == nullptr) { return; }
75+
clear_highlights();
6876
for (size_t i = 0; i < machine::CSR::REGISTERS.size(); i++) {
69-
labelVal(csr_view[i], controlst->read_internal(i).as_xlen(xlen));
77+
labelVal(csr_view[i], csr_handle->read_internal(i).as_xlen(xlen));
7078
}
71-
72-
connect(controlst, &machine::CSR::ControlState::write_signal, this, &CsrDock::csr_changed);
73-
connect(controlst, &machine::CSR::ControlState::read_signal, this, &CsrDock::csr_read);
74-
connect(machine, &machine::Machine::tick, this, &CsrDock::clear_highlights);
7579
}
7680

7781
void CsrDock::csr_changed(size_t internal_reg_id, machine::RegisterValue val) {
82+
if (isHidden()) { return; }
83+
7884
// FIXME assert takes literal
7985
SANITY_ASSERT(
8086
(uint)internal_reg_id < machine::CSR::REGISTERS.size(),
@@ -88,6 +94,9 @@ void CsrDock::csr_changed(size_t internal_reg_id, machine::RegisterValue val) {
8894

8995
void CsrDock::csr_read(size_t internal_reg_id, machine::RegisterValue val) {
9096
(void)val;
97+
98+
if (isHidden()) { return; }
99+
91100
// FIXME assert takes literal
92101
SANITY_ASSERT(
93102
(uint)internal_reg_id < machine::CSR::REGISTERS.size(),
@@ -109,7 +118,13 @@ void CsrDock::clear_highlights() {
109118
csr_highlighted_any = false;
110119
}
111120

121+
void CsrDock::showEvent(QShowEvent *event) {
122+
// Slots are inactive when this widget is hidden
123+
reload();
124+
QDockWidget::showEvent(event);
125+
}
126+
112127
void CsrDock::labelVal(QLabel *label, uint64_t value) {
113128
QString t = QString("0x") + QString::number(value, 16);
114129
label->setText(t);
115-
}
130+
}

src/gui/windows/csr/csrdock.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,20 @@ class CsrDock : public QDockWidget {
1818
explicit CsrDock(QWidget *parent);
1919

2020
void setup(machine::Machine *machine);
21+
void reload();
2122

2223
private slots:
2324
void csr_changed(std::size_t internal_reg_id, machine::RegisterValue val);
2425
void csr_read(std::size_t internal_reg_id, machine::RegisterValue val);
2526
void clear_highlights();
2627

28+
private:
29+
void showEvent(QShowEvent *event) override;
30+
2731
private:
2832
machine::Xlen xlen;
33+
// We keep this handle for batch updates when this widget was hidden.
34+
const machine::CSR::ControlState *csr_handle {};
2935

3036
const char *sizeHintText();
3137

src/gui/windows/memory/memorymodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ QVariant MemoryModel::data(const QModelIndex &index, int role) const {
6464
if (index.column() == 0) {
6565
t = QString::number(address.get_raw(), 16);
6666
s.fill('0', 8 - t.count());
67-
return "0x" + s + t;
67+
return { QString("0x") + s + t };
6868
}
6969
if (machine == nullptr) { return QString(""); }
7070
mem = mem_access();

0 commit comments

Comments
 (0)