aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2026-04-15 03:46:23 +0200
committerPaul Oliver <contact@pauloliver.dev>2026-04-15 03:46:23 +0200
commit21b6fc1eb1fddc817aa493fe89b14cad0cda65a0 (patch)
treea1506d90a7a3af4aafc76fe26f8e39cef3d0cf00
parent8c56bc6ebf71ff94694ac456447acc2dc8b0ed72 (diff)
Adds more heatmaps
-rw-r--r--arch/v1/arch.c32
-rw-r--r--arch/v1/arch_vars.py7
-rw-r--r--core/salis.c25
-rw-r--r--data/vue/App.vue38
-rwxr-xr-xsalis.py4
5 files changed, 86 insertions, 20 deletions
diff --git a/arch/v1/arch.c b/arch/v1/arch.c
index f336dd6..a5f9dd4 100644
--- a/arch/v1/arch.c
+++ b/arch/v1/arch.c
@@ -47,6 +47,7 @@ void arch_core_save(FILE *f, const struct Core *core) {
fwrite(&core->wmb1, sizeof(uint64_t), 1, f);
fwrite(&core->wdea, sizeof(uint64_t), 1, f);
fwrite(core->weva, sizeof(uint64_t), MVEC_SIZE, f);
+ fwrite(core->xeva, sizeof(uint64_t), MVEC_SIZE, f);
#else
(void)f;
(void)core;
@@ -66,6 +67,7 @@ void arch_core_load(FILE *f, struct Core *core) {
fread(&core->wmb1, sizeof(uint64_t), 1, f);
fread(&core->wdea, sizeof(uint64_t), 1, f);
fread(core->weva, sizeof(uint64_t), MVEC_SIZE, f);
+ fread(core->xeva, sizeof(uint64_t), MVEC_SIZE, f);
#else
(void)f;
(void)core;
@@ -415,6 +417,29 @@ void _bswap(struct Core *core, uint64_t pix) {
proc->mb0s = proc->mb1s;
proc->mb1a = tmpa;
proc->mb1s = tmps;
+
+#if defined(DATA_PUSH_PATH)
+ // Memory block swap events mark all addresses within both blocks
+ for (uint64_t i = 0; i < proc->mb0s; i++) {
+ uint64_t addr = proc->mb0a + i;
+
+#if defined(MVEC_LOOP)
+ ++core->xeva[mvec_loop(addr)];
+#else
+ ++core->xeva[addr];
+#endif
+ }
+
+ for (uint64_t i = 0; i < proc->mb1s; i++) {
+ uint64_t addr = proc->mb1a + i;
+
+#if defined(MVEC_LOOP)
+ ++core->xeva[mvec_loop(addr)];
+#else
+ ++core->xeva[addr];
+#endif
+ }
+#endif
}
_increment_ip(core, pix);
@@ -872,7 +897,7 @@ void arch_push_data_header(void) {
}
// Memory events
- char *eprefs[] = { "wev" };
+ char *eprefs[] = { "wev", "xev" };
int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]);
for (int i = 0; i < CORES; ++i) {
@@ -996,7 +1021,7 @@ void arch_push_data_line(void) {
}
// TODO: insert write memory events
- char *eprefs[] = { "wev" };
+ char *eprefs[] = { "wev", "xev" };
int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]);
for (int i = 0; i < CORES; ++i) {
@@ -1005,6 +1030,8 @@ void arch_push_data_line(void) {
if (!strcmp("wev", eprefs[j])) {
in = g_cores[i].weva;
+ } else if (!strcmp("xev", eprefs[j])) {
+ in = g_cores[i].xeva;
}
// Compress event data
@@ -1057,6 +1084,7 @@ void arch_push_data_line(void) {
core->wdea = 0;
memset(core->weva, 0, sizeof(uint64_t) * MVEC_SIZE);
+ memset(core->xeva, 0, sizeof(uint64_t) * MVEC_SIZE);
}
}
#endif
diff --git a/arch/v1/arch_vars.py b/arch/v1/arch_vars.py
index c794a29..4fb6bb2 100644
--- a/arch/v1/arch_vars.py
+++ b/arch/v1/arch_vars.py
@@ -84,6 +84,7 @@ class ArchVars:
("uint64_t", "wdea", ""), # writes within dead code counter
("uint64_t", "weva", f"[{2 ** args.mvec_pow}]"), # write events array
+ ("uint64_t", "xeva", f"[{2 ** args.mvec_pow}]"), # memory block swap events array
]
self.mvec_loop = False
@@ -143,5 +144,9 @@ class ArchVars:
f"wev_{i}": {
"table": f"wev_{i}",
} for i in range(args.cores)
- }
+ } | {
+ f"xev_{i}": {
+ "table": f"xev_{i}",
+ } for i in range(args.cores)
+ },
}
diff --git a/core/salis.c b/core/salis.c
index 5bccc15..7168dea 100644
--- a/core/salis.c
+++ b/core/salis.c
@@ -51,6 +51,7 @@ struct Core {
uint64_t aeva[MVEC_SIZE]; // allocation events array
uint64_t eeva[MVEC_SIZE]; // execution events array
+ uint64_t beva[MVEC_SIZE]; // birth events array
#define CORE_DATA_FIELD(type, name, suff) type name suff;
CORE_DATA_FIELDS
@@ -361,6 +362,21 @@ void proc_new(struct Core *core, const struct Proc *proc) {
core->pnum++;
core->plst++;
memcpy(&core->pvec[core->plst % core->pcap], proc, sizeof(struct Proc));
+
+#if defined(DATA_PUSH_PATH)
+ // Store birth event in database
+ uint64_t child_addr = arch_proc_mb0_addr(core, core->plst);
+ uint64_t child_size = arch_proc_mb0_size(core, core->plst);
+
+ for (uint64_t i = 0; i < child_size; i++) {
+ uint64_t addr = child_addr + i;
+#if defined(MVEC_LOOP)
+ ++core->beva[mvec_loop(addr)];
+#else
+ ++core->beva[addr];
+#endif
+ }
+#endif
}
void proc_kill(struct Core *core) {
@@ -423,6 +439,7 @@ void core_save(FILE *f, const struct Core *core) {
#if defined(DATA_PUSH_PATH)
fwrite(core->aeva, sizeof(uint64_t), MVEC_SIZE, f);
fwrite(core->eeva, sizeof(uint64_t), MVEC_SIZE, f);
+ fwrite(core->beva, sizeof(uint64_t), MVEC_SIZE, f);
#endif
arch_core_save(f, core);
@@ -519,6 +536,7 @@ void core_load(FILE *f, struct Core *core) {
#if defined(DATA_PUSH_PATH)
fread(core->aeva, sizeof(uint64_t), MVEC_SIZE, f);
fread(core->eeva, sizeof(uint64_t), MVEC_SIZE, f);
+ fread(core->beva, sizeof(uint64_t), MVEC_SIZE, f);
#endif
arch_core_load(f, core);
@@ -763,7 +781,7 @@ void salis_push_data_header(void) {
);
// Memory events
- char *eprefs[] = { "aev", "eev" };
+ char *eprefs[] = { "aev", "eev", "bev" };
int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]);
for (int i = 0; i < CORES; ++i) {
@@ -850,7 +868,7 @@ void salis_push_data_line(void) {
);
// TODO: insert execute memory events
- char *eprefs[] = { "aev", "eev" };
+ char *eprefs[] = { "aev", "eev", "bev" };
int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]);
for (int i = 0; i < CORES; ++i) {
@@ -861,6 +879,8 @@ void salis_push_data_line(void) {
in = g_cores[i].aeva;
} else if (!strcmp("eev", eprefs[j])) {
in = g_cores[i].eeva;
+ } else if (!strcmp("bev", eprefs[j])) {
+ in = g_cores[i].beva;
}
// Compress event data
@@ -912,6 +932,7 @@ void salis_push_data_line(void) {
memset(core->aeva, 0, sizeof(uint64_t) * MVEC_SIZE);
memset(core->eeva, 0, sizeof(uint64_t) * MVEC_SIZE);
+ memset(core->beva, 0, sizeof(uint64_t) * MVEC_SIZE);
}
// Push arch-specific data
diff --git a/data/vue/App.vue b/data/vue/App.vue
index f8f4b41..cb04565 100644
--- a/data/vue/App.vue
+++ b/data/vue/App.vue
@@ -9,14 +9,14 @@
</span>
</h1>
<form @change="trigger_reload">
- <span class="nobr">Entries: <input v-model="entries" /></span><wbr />
- <span class="nobr">nth: <input v-model="nth" /></span><wbr />
- <span class="nobr">X-axis: <select v-model="x_axis"><option v-for="axis in x_axes">{{ axis }}</option></select></span><wbr />
+ <span class="nobr">Entries: <input class="input_small" v-model="entries" /></span><wbr />
+ <span class="nobr">nth: <input class="input_small" v-model="nth" /></span><wbr />
+ <span class="nobr">X-axis: <select class="input_small" v-model="x_axis"><option v-for="axis in x_axes">{{ axis }}</option></select></span><wbr />
<span class="nobr">X-low: <input v-model="x_low" /></span><wbr />
<span class="nobr">X-high: <input v-model="x_high" /></span><wbr />
- <span class="nobr">Left: <input v-model="hm_left" /></span><wbr />
- <span class="nobr">Px-count: <input v-model="hm_px_count" /></span><wbr />
- <span class="nobr">Px-pow: <input v-model="hm_px_pow" /></span><wbr />
+ <span class="nobr">Left: <input class="input_small" v-model="hm_left" /></span><wbr />
+ <span class="nobr">Px-count: <input class="input_small" v-model="hm_px_count" /></span><wbr />
+ <span class="nobr">Px-pow: <input class="input_small" v-model="hm_px_pow" /></span><wbr />
<span class="reset_button" @click="reset_inputs">↻</span>
</form>
</div>
@@ -72,6 +72,7 @@ let plot_x_low = 0
let plot_redraw = false
let mvec_size = 0
+const int_max = Number.MAX_SAFE_INTEGER
const uint32_max = (2 ** 32) - 1
const hm_max_pixels = 2 ** 11
@@ -79,7 +80,7 @@ const entries_def = 2000
const nth_def = 1
const x_axis_def = 'rowid'
const x_low_def = hex(0)
-const x_high_def = hex(uint32_max)
+const x_high_def = hex(int_max)
const hm_left_def = hex(0)
const hm_px_count_def = hex(2 ** 10)
@@ -106,6 +107,8 @@ const top_bar = useTemplateRef('top_bar')
const plot_sections = useTemplateRef('plot_sections')
const heatmap_sections = useTemplateRef('heatmap_sections')
+const adjust_top_bar = () => top_pad.value.style.height = `${Math.round(top_bar.value.getBoundingClientRect().height)}px`
+
const update_visible_tables = () => {
const plot_section_visibility = plot_sections.value.map(section => section.visible)
const heatmap_section_visibility = heatmap_sections.value.map(section => section.visible)
@@ -124,18 +127,18 @@ const max_hm_px_pow = () => Math.floor(Math.log2((mvec_size - Number(hm_left.val
const trigger_reload = () => {
update_visible_tables()
- sanitize(entries, 1, uint32_max, 2000, id)
- sanitize(nth, 1, uint32_max, 1, id)
- sanitize(x_low, 0, uint32_max, 0, hex)
- sanitize(x_high, 1, uint32_max, uint32_max, hex)
+ sanitize(entries, 1, uint32_max, entries_def, id)
+ sanitize(nth, 1, uint32_max, nth_def, id)
+ sanitize(x_low, 0, int_max, 0, hex)
+ sanitize(x_high, 1, int_max, int_max, hex)
if (opts.value.mvec_loop) {
sanitize(hm_left, 0, uint32_max, 0, hex)
- sanitize(hm_px_count, 1, hm_max_pixels, hm_max_pixels, hex)
+ sanitize(hm_px_count, 1, hm_max_pixels, 2 ** 10, hex)
sanitize(hm_px_pow, 0, uint32_max, uint32_max, hex)
} else {
sanitize(hm_left, 0, mvec_size, 0, hex)
- sanitize(hm_px_count, 1, hm_max_pixels, hm_max_pixels, hex)
+ sanitize(hm_px_count, 1, hm_max_pixels, 2 ** 10, hex)
sanitize(hm_px_pow, 0, max_hm_px_pow(), max_hm_px_pow(), hex)
}
@@ -239,8 +242,9 @@ onMounted(async () => {
})
watch(loaded, _ => {
- top_pad.value.style.height = `${Math.round(top_bar.value.getBoundingClientRect().height)}px`
+ window.addEventListener('resize', adjust_top_bar)
+ adjust_top_bar()
update_visible_tables()
query()
}, { flush: 'post' })
@@ -277,7 +281,7 @@ input, select {
font-size: 12px;
margin: 0 4px;
padding: 2px;
- width: 80px;
+ width: 120px;
}
table {
@@ -321,6 +325,10 @@ td {
white-space: nowrap;
}
+.input_small {
+ width: 80px;
+}
+
.reset_button {
background-color: black;
border: 1.5px solid gray;
diff --git a/salis.py b/salis.py
index f56864c..afb8099 100755
--- a/salis.py
+++ b/salis.py
@@ -299,6 +299,10 @@ if args.command in ["serve"]:
f"eev_{i}": {
"table": f"eev_{i}",
} for i in range(args.cores)
+ } | {
+ f"bev_{i}": {
+ "table": f"bev_{i}",
+ } for i in range(args.cores)
},
}