Skip to content

Commit 2a4153e

Browse files
authored
GUI: Significant speedup (#155)
2 parents 2dc5ac4 + 4e0bd5d commit 2a4153e

21 files changed

+411
-153
lines changed

CMakeLists.txt

+9
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/mainwindow/mainwindow.cpp

+32-23
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
#include "windows/editor/editordock.h"
2-
#include "windows/editor/editortab.h"
3-
4-
#include <QProcessEnvironment>
5-
#include <QtWidgets>
6-
#include <qactiongroup.h>
7-
#include <qwidget.h>
1+
#include "mainwindow.h"
82

93
#include "assembler/fixmatheval.h"
104
#include "assembler/simpleasm.h"
@@ -13,15 +7,19 @@
137
#include "dialogs/savechanged/savechangeddialog.h"
148
#include "extprocess.h"
159
#include "helper/async_modal.h"
16-
#include "mainwindow.h"
1710
#include "os_emulation/ossyscall.h"
1811
#include "textsignalaction.h"
19-
#include "common/logging.h"
12+
#include "windows/editor/editordock.h"
13+
#include "windows/editor/editortab.h"
2014

2115
#include <QFileInfo>
2216
#include <QMessageBox>
2317
#include <QMetaObject>
18+
#include <QProcessEnvironment>
2419
#include <QTextDocument>
20+
#include <QtWidgets>
21+
#include <qactiongroup.h>
22+
#include <qwidget.h>
2523

2624
LOG_CATEGORY("gui.mainwindow");
2725

@@ -46,6 +44,9 @@ MainWindow::MainWindow(QSettings *settings, QWidget *parent)
4644
setWindowTitle(APP_NAME);
4745
setDockNestingEnabled(true);
4846

47+
frequency_label.reset(new QLabel(this));
48+
ui->statusBar->addPermanentWidget(frequency_label.data());
49+
4950
// Setup central widget
5051

5152
central_widget_tabs.reset(new HidingTabWidget(this));
@@ -168,9 +169,7 @@ MainWindow::MainWindow(QSettings *settings, QWidget *parent)
168169
connect(
169170
ui->actionBranch_Predictor_Target_table, &QAction::triggered, this,
170171
&MainWindow::show_bp_btb);
171-
connect(
172-
ui->actionBranch_Predictor_Info, &QAction::triggered, this,
173-
&MainWindow::show_bp_info);
172+
connect(ui->actionBranch_Predictor_Info, &QAction::triggered, this, &MainWindow::show_bp_info);
174173

175174
connect(ui->actionPeripherals, &QAction::triggered, this, &MainWindow::show_peripherals);
176175
connect(ui->actionTerminal, &QAction::triggered, this, &MainWindow::show_terminal);
@@ -286,8 +285,9 @@ void MainWindow::create_core(
286285

287286
set_speed(); // Update machine speed to current settings
288287

289-
const static machine::ExceptionCause ecall_variats[] = {machine::EXCAUSE_ECALL_ANY,
290-
machine::EXCAUSE_ECALL_M, machine::EXCAUSE_ECALL_S, machine::EXCAUSE_ECALL_U};
288+
const static machine::ExceptionCause ecall_variats[]
289+
= { machine::EXCAUSE_ECALL_ANY, machine::EXCAUSE_ECALL_M, machine::EXCAUSE_ECALL_S,
290+
machine::EXCAUSE_ECALL_U };
291291

292292
if (config.osemu_enable()) {
293293
auto *osemu_handler = new osemu::OsSyscallExceptionHandler(
@@ -320,6 +320,9 @@ void MainWindow::create_core(
320320
connect(machine.data(), &machine::Machine::status_change, this, &MainWindow::machine_status);
321321
connect(machine.data(), &machine::Machine::program_exit, this, &MainWindow::machine_exit);
322322
connect(machine.data(), &machine::Machine::program_trap, this, &MainWindow::machine_trap);
323+
connect(
324+
machine.data(), &machine::Machine::report_core_frequency, this,
325+
&MainWindow::update_core_frequency);
323326
// Connect signal from break to machine pause
324327
connect(
325328
machine->core(), &machine::Core::stop_on_exception_reached, machine.data(),
@@ -434,13 +437,13 @@ void MainWindow::print_action() {
434437
void MainWindow::show_##NAME() { \
435438
show_dockwidget(&*NAME, DEFAULT_AREA, true, false); \
436439
} \
437-
void MainWindow::reset_state_##NAME() { \
438-
show_dockwidget(&*NAME, DEFAULT_AREA, DEFAULT_VISIBLE, true); \
439-
}
440+
void MainWindow::reset_state_##NAME() { \
441+
show_dockwidget(&*NAME, DEFAULT_AREA, DEFAULT_VISIBLE, true); \
442+
}
440443

441444
SHOW_HANDLER(registers, Qt::TopDockWidgetArea, true)
442445
SHOW_HANDLER(program, Qt::LeftDockWidgetArea, true)
443-
SHOW_HANDLER(memory, Qt::RightDockWidgetArea, true )
446+
SHOW_HANDLER(memory, Qt::RightDockWidgetArea, true)
444447
SHOW_HANDLER(cache_program, Qt::RightDockWidgetArea, false)
445448
SHOW_HANDLER(cache_data, Qt::RightDockWidgetArea, false)
446449
SHOW_HANDLER(cache_level2, Qt::RightDockWidgetArea, false)
@@ -558,8 +561,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
558561
}
559562
}
560563

561-
void MainWindow::show_dockwidget(QDockWidget *dw, Qt::DockWidgetArea area,
562-
bool defaultVisible, bool resetState) {
564+
void MainWindow::show_dockwidget(
565+
QDockWidget *dw,
566+
Qt::DockWidgetArea area,
567+
bool defaultVisible,
568+
bool resetState) {
563569
if (dw == nullptr) { return; }
564570
if (resetState) {
565571
if (dw->isFloating()) {
@@ -651,8 +657,7 @@ void MainWindow::message_selected(
651657
central_widget_tabs->setCurrentWidget(editor_tabs.data());
652658
if (!editor_tabs->set_cursor_to(file, line, column)) {
653659
editor_tabs->open_file_if_not_open(file, false);
654-
if (!editor_tabs->set_cursor_to(file, line, column))
655-
return;
660+
if (!editor_tabs->set_cursor_to(file, line, column)) return;
656661
}
657662

658663
// Highlight the line
@@ -665,8 +670,12 @@ void MainWindow::message_selected(
665670
editor->setExtraSelections({ selection });
666671
}
667672

673+
void MainWindow::update_core_frequency(double frequency) {
674+
frequency_label->setText(QString("Core frequency: %1 kHz").arg(frequency / 1000.0, 0, 'f', 3));
675+
}
676+
668677
bool SimpleAsmWithEditorCheck::process_file(const QString &filename, QString *error_ptr) {
669-
EditorTab* tab = mainwindow->editor_tabs->find_tab_by_filename(filename);
678+
EditorTab *tab = mainwindow->editor_tabs->find_tab_by_filename(filename);
670679
if (tab == nullptr) { return Super::process_file(filename, error_ptr); }
671680
SrcEditor *editor = tab->get_editor();
672681
QTextDocument *doc = editor->document();

src/gui/mainwindow/mainwindow.h

+4
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,16 @@ public slots:
121121
int column,
122122
const QString &text,
123123
const QString &hint);
124+
// Update data
125+
void update_core_frequency(double frequency);
124126

125127
protected:
126128
void closeEvent(QCloseEvent *cancel) override;
127129

128130
private:
129131
Box<Ui::MainWindow> ui {};
132+
// Placed right on bottom status bar.
133+
Box<QLabel> frequency_label {};
130134

131135
Box<NewDialog> ndialog {};
132136
Box<HidingTabWidget> central_widget_tabs {};

src/gui/windows/cache/cachedock.cpp

+31-19
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ CacheDock::CacheDock(QWidget *parent, const QString &type)
3939
}
4040

4141
void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
42+
memory_reads = 0;
43+
memory_writes = 0;
44+
hit = 0;
45+
miss = 0;
46+
stalled = 0;
47+
speed_improv = 0.0;
48+
hit_rate = 0.0;
49+
4250
l_hit->setText("0");
4351
l_miss->setText("0");
4452
l_stalled->setText("0");
@@ -48,19 +56,12 @@ void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
4856
l_speed->setText("100%");
4957
l_speed->setHidden(cache_after_cache);
5058
if (cache != nullptr) {
59+
connect(cache, &machine::Cache::hit_update, this, &CacheDock::hit_update);
60+
connect(cache, &machine::Cache::miss_update, this, &CacheDock::miss_update);
61+
connect(cache, &machine::Cache::memory_reads_update, this, &CacheDock::memory_reads_update);
5162
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);
63+
cache, &machine::Cache::memory_writes_update, this, &CacheDock::memory_writes_update);
64+
connect(cache, &machine::Cache::statistics_update, this, &CacheDock::statistics_update);
6465
}
6566
top_form->setVisible(cache != nullptr);
6667
no_cache->setVisible(cache == nullptr || !cache->get_config().enabled());
@@ -71,27 +72,38 @@ void CacheDock::setup(const machine::Cache *cache, bool cache_after_cache) {
7172
graphicsview->setVisible(cache != nullptr && cache->get_config().enabled());
7273
}
7374

75+
void CacheDock::paintEvent(QPaintEvent *event) {
76+
l_stalled->setText(QString::number(stalled));
77+
l_hit_rate->setText(QString::number(hit_rate, 'f', 3) + QString("%"));
78+
l_speed->setText(QString::number(speed_improv, 'f', 0) + QString("%"));
79+
l_hit->setText(QString::number(hit));
80+
l_miss->setText(QString::number(miss));
81+
l_m_reads->setText(QString::number(memory_reads));
82+
l_m_writes->setText(QString::number(memory_writes));
83+
QDockWidget::paintEvent(event);
84+
}
85+
7486
void CacheDock::hit_update(unsigned val) {
75-
l_hit->setText(QString::number(val));
87+
hit = val;
7688
}
7789

7890
void CacheDock::miss_update(unsigned val) {
79-
l_miss->setText(QString::number(val));
91+
miss = val;
8092
}
8193

8294
void CacheDock::memory_reads_update(unsigned val) {
83-
l_m_reads->setText(QString::number(val));
95+
memory_reads = val;
8496
}
8597

8698
void CacheDock::memory_writes_update(unsigned val) {
87-
l_m_writes->setText(QString::number(val));
99+
memory_writes = val;
88100
}
89101

90102
void CacheDock::statistics_update(
91103
unsigned stalled_cycles,
92104
double speed_improv,
93105
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("%"));
106+
this->stalled = stalled_cycles;
107+
this->hit = hit_rate;
108+
this->speed_improv = speed_improv;
97109
}

src/gui/windows/cache/cachedock.h

+11
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

+10-6
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

0 commit comments

Comments
 (0)