From 7e1bb9daec29f1ea987741b77ae567094b8b229a Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Thu, 20 Jul 2023 23:23:19 +0300 Subject: [PATCH] reduce memory footprint --- Makefile | 2 +- src/main.cpp | 63 ++++++++++++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index dcd7a11..3557975 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ WEB_HEAP_SIZE := 1105199104 WEB_STACK_SIZE := 262144 WEB_SHELL := src/shell.html -COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -s -O0 +COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -s -O1 LINKER_FLAGS := -lraylib # SOURCES := $(wildcard src/*.cpp) diff --git a/src/main.cpp b/src/main.cpp index 3999404..3e9902f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -209,6 +209,26 @@ static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_t *v return true; } +static void boid_list_append(MemoryArena *arena, BoidsListNode *node, uint16_t *count, uint16_t new_boid) { + int left_count = *count; + BoidsListNode *prev = node; + BoidsListNode *curr = node; + while (left_count > BOIDS_PER_NODE && curr) { + prev = curr; + curr = curr->next; + left_count -= BOIDS_PER_NODE; + } + + if (curr == NULL) { + curr = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode)); + curr->next = NULL; + prev->next = curr; + } + + prev->boid_ids[left_count] = new_boid; + (*count)++; +} + static void boid_list_append_unique(MemoryArena *arena, BoidsListNode *local_boids, uint16_t *count, uint16_t new_boid) { int left_count = *count; BoidsListNode *last = local_boids; @@ -261,11 +281,9 @@ static void world_update(World *world, float dt) { assert(boid_count <= MAX_BOIDS); RPROF_START("Alloc groups"); - // LocalBoidsListNode all_local_boids[boid_count]; BoidsListNode *all_local_boids = (BoidsListNode*)arena_malloc(&world->frame_arena, boid_count * sizeof(BoidsListNode)); uint16_t all_local_boid_counts[boid_count]; for (int i = 0; i < boid_count; i++) { - // all_local_boids[i] = (uint16_t *)arena_malloc(&world->frame_arena, boid_count * sizeof(uint16_t)); all_local_boids[i].next = NULL; all_local_boid_counts[i] = 0; } @@ -276,11 +294,12 @@ static void world_update(World *world, float dt) { int chunks_wide = std::ceil(world->size.x / chunk_size) + 1; int chunks_high = std::ceil(world->size.y / chunk_size) + 1; RPROF_START("Alloc chunks"); - uint16_t *chunks[chunks_high][chunks_wide]; + BoidsListNode *chunks[chunks_high][chunks_wide]; uint16_t chunk_boid_counts[chunks_high][chunks_wide]; for (int y = 0; y < chunks_high; y++) { for (int x = 0; x < chunks_wide; x++) { - chunks[y][x] = (uint16_t*)arena_malloc(&world->frame_arena, boid_count * sizeof(uint16_t)); + chunks[y][x] = (BoidsListNode*)arena_malloc(&world->frame_arena, sizeof(BoidsListNode)); + chunks[y][x]->next = NULL; chunk_boid_counts[y][x] = 0; } } @@ -291,17 +310,13 @@ static void world_update(World *world, float dt) { Boid *boid = &boids[i]; int chunk_x = boid->pos.x / chunk_size; int chunk_y = boid->pos.y / chunk_size; - - uint16_t *count = &chunk_boid_counts[chunk_y][chunk_x]; - chunks[chunk_y][chunk_x][*count] = i; - (*count)++; } RPROF_STOP(); RPROF_START("Calc dot products and ranges (chunked)"); for (int y = 0; y < chunks_high; y++) { for (int x = 0; x < chunks_high; x++) { - uint16_t *chunk = chunks[y][x]; + BoidsListNode *chunk = chunks[y][x]; size_t chunk_boid_count = chunk_boid_counts[y][x]; for (int oy = -1; oy <= 1; oy++) { @@ -312,30 +327,20 @@ static void world_update(World *world, float dt) { int chunk_x = y + ox; if (chunk_x < 0 || chunk_x >= chunks_wide) continue; - uint16_t *neighbour_chunk = chunks[chunk_y][chunk_x]; + BoidsListNode *neighbour_chunk = chunks[chunk_y][chunk_x]; size_t neighbour_chunk_boid_count = chunk_boid_counts[chunk_y][chunk_x]; - for (int i = 0; i < chunk_boid_count; i++) { - int boid1 = chunk[i]; - for (int j = 0; j < neighbour_chunk_boid_count; j++) { - int boid2 = chunk[j]; + uint16_t boid1; + BoidsListNodeIterator it1 = boid_list_get_iterator(chunk, chunk_boid_count); + while (boid_list_iterator_next(&it1, &boid1)) { + uint16_t boid2; + BoidsListNodeIterator it2 = boid_list_get_iterator(neighbour_chunk, neighbour_chunk_boid_count); + while (boid_list_iterator_next(&it2, &boid2)) { if (boid1 == boid2) continue; assign_local_boids(world, all_local_boids, all_local_boid_counts, boids, boid1, boid2); } } - - // uint16_t boid1; - // BoidsListNodeIterator it1 = boid_list_get_iterator(chunk, chunk_boid_count); - // while (boid_list_iterator_next(&it1, &boid1)) { - // uint16_t boid2; - // BoidsListNodeIterator it2 = boid_list_get_iterator(neighbour_chunk, neighbour_chunk_boid_count); - // while (boid_list_iterator_next(&it2, &boid2)) { - // if (boid1 == boid2) continue; - // - // assign_local_boids(world, all_local_boids, all_local_boid_counts, boids, boid1, boid2); - // } - // } } } } @@ -669,7 +674,7 @@ int estimate_maximum_boid_count(World *world) { return boid_count; } -int main() { +int foo_main() { rprof_init(); world_init(&g_world, 1280, 720); @@ -695,7 +700,7 @@ int main() { return 0; } -int foo_main() { +int main() { SetTraceLogLevel(LOG_TRACE); int screen_width = 1280; @@ -712,7 +717,7 @@ int foo_main() { world_init(&g_world, screen_width, screen_height); float border = g_world.collision_avoidance_distance; - for (int i = 0; i < 50000; i++) { + for (int i = 0; i < MAX_BOIDS; i++) { Boid boid; boid_rand_init(&g_world, &boid, border); g_world.boids.push_back(boid);