diff --git a/Makefile b/Makefile index 3557975..a0ebeb8 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ TOP_BUILD_DIR := build EXECUTABLE := boids-playground SUBMODULES_PATH := depends -# default stack - 65536 -# 67108864 = 64MiB -WEB_HEAP_SIZE := 1105199104 -WEB_STACK_SIZE := 262144 +# WEB_HEAP_SIZE default: 16777216 (16MiB) +WEB_HEAP_SIZE := 335544320 +# WEB_STACK_SIZE default: 65536 (64KiB) +WEB_STACK_SIZE := 196608 WEB_SHELL := src/shell.html -COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -s -O1 +COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -O2 LINKER_FLAGS := -lraylib # SOURCES := $(wildcard src/*.cpp) diff --git a/src/boid-list.cpp b/src/boid-list.cpp new file mode 100644 index 0000000..61b2c12 --- /dev/null +++ b/src/boid-list.cpp @@ -0,0 +1,67 @@ +#include + +#include "boid-list.hpp" + +static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count) { + return { .node = node, .i = 0, .count = count }; +} + +static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_t *value) { + if (iterator->count == 0) { + return false; + } + + if (iterator->i == BOIDS_PER_NODE) { + iterator->i = 0; + iterator->node = iterator->node->next; + } + + *value = iterator->node->boid_ids[iterator->i]; + iterator->i++; + iterator->count--; + 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; + BoidsListNode *curr = local_boids; + while (left_count > 0 && curr) { + for (int i = 0; i < std::min(left_count, BOIDS_PER_NODE); i++) { + if (curr->boid_ids[i] == new_boid) return; + } + + last = curr; + curr = curr->next; + left_count -= BOIDS_PER_NODE; + } + + int idx = (*count) % BOIDS_PER_NODE; + if (idx == BOIDS_PER_NODE-1) { + last->next = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode)); + last->next->next = NULL; + } + + last->boid_ids[idx] = new_boid; + (*count)++; +} diff --git a/src/boid-list.hpp b/src/boid-list.hpp new file mode 100644 index 0000000..cdd863e --- /dev/null +++ b/src/boid-list.hpp @@ -0,0 +1,22 @@ +#include + +#include "memory-arena.hpp" + +#define BOIDS_PER_NODE 32 + +struct BoidsListNode { + uint16_t boid_ids[BOIDS_PER_NODE]; + BoidsListNode *next; +}; + +struct BoidsListNodeIterator { + BoidsListNode *node; + int i; + uint16_t count; +}; + +static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count); +static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_t *value); + +static void boid_list_append(MemoryArena *arena, BoidsListNode *node, uint16_t *count, uint16_t new_boid); +static void boid_list_append_unique(MemoryArena *arena, BoidsListNode *local_boids, uint16_t *count, uint16_t new_boid); diff --git a/src/boid-playground.hpp b/src/boid-playground.hpp index 22ef10c..1566bc5 100644 --- a/src/boid-playground.hpp +++ b/src/boid-playground.hpp @@ -82,16 +82,3 @@ struct UI { bool separation_strength_edit = false; bool collision_avoidance_strength_edit = false; }; - -#define BOIDS_PER_NODE 32 - -struct BoidsListNode { - uint16_t boid_ids[BOIDS_PER_NODE]; - BoidsListNode *next; -}; - -struct BoidsListNodeIterator { - BoidsListNode *node; - int i; - uint16_t count; -}; diff --git a/src/main.cpp b/src/main.cpp index 3e9902f..9fc1922 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,12 +12,13 @@ #include "raygui.h" #define RPROF_IMPLEMENTATION -// #define RPROF_ONLY_TOTAL_TIME +#define RPROF_STUB_OUT #include "rprof.h" #include "boid-playground.hpp" #include "raycast.cpp" #include "memory-arena.cpp" +#include "boid-list.cpp" #define FRAMERATE 60 #define TIME_PER_FRAME (1.0/FRAMERATE) @@ -54,7 +55,7 @@ static void boid_rand_init(World *world, Boid *boid, float border) { } static void world_init(World *world, float width, float height) { - arena_init(&world->frame_arena, 1024 * 1024 * 1024); + arena_init(&world->frame_arena, 1024 * 1024 * 256); g_world.size = { width, height }; } @@ -189,70 +190,6 @@ static void draw_circle_sector(Vector2 center, float radius, float start_angle, rlEnd(); } -static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count) { - return { .node = node, .i = 0, .count = count }; -} - -static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_t *value) { - if (iterator->count == 0) { - return false; - } - - if (iterator->i == BOIDS_PER_NODE) { - iterator->i = 0; - iterator->node = iterator->node->next; - } - - *value = iterator->node->boid_ids[iterator->i]; - iterator->i++; - iterator->count--; - 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; - BoidsListNode *curr = local_boids; - while (left_count > 0 && curr) { - for (int i = 0; i < MIN(left_count, BOIDS_PER_NODE); i++) { - if (curr->boid_ids[i] == new_boid) return; - } - - last = curr; - curr = curr->next; - left_count -= BOIDS_PER_NODE; - } - - int idx = (*count) % BOIDS_PER_NODE; - if (idx == BOIDS_PER_NODE-1) { - last->next = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode)); - last->next->next = NULL; - } - - last->boid_ids[idx] = new_boid; - (*count)++; -} - static void assign_local_boids(World *world, BoidsListNode *local_boids, uint16_t *local_boid_counts, Boid *boids, uint16_t boid1, uint16_t boid2) { // Simplified from: float dot_threshold = Vector2DotProduct(dir, Vector2Rotate(dir, world->view_angle/2)); float dot_threshold = cosf(world->view_angle/2); @@ -626,78 +563,28 @@ void UpdateDrawFrame() { EndDrawing(); } -int estimate_maximum_boid_count(World *world) { - int boid_count = 1000; - int prev_boid_count = 0; +void stress_test() { + rprof_init(); + { + world_init(&g_world, 1280, 720); - uint64_t cpu_hz = rprof_get_cpu_timer_hz(100); - - do { - world->boids.clear(); - for (int i = 0; i < boid_count; i++) { + float border = g_visuals.boid_edge_size; + for (int i = 0; i < MAX_BOIDS; i++) { Boid boid; - boid_rand_init(&g_world, &boid, 0); + boid_rand_init(&g_world, &boid, border); g_world.boids.push_back(boid); } - uint64_t best_duration = UINT64_MAX; - for (int i = 0; i < 20; i++) { - uint64_t start = rprof_read_cpu_timer(); + for (int i = 0; i < 1; i++) { world_update(&g_world, TIME_PER_FRAME); - uint64_t end = rprof_read_cpu_timer(); - best_duration = std::min(best_duration, (end - start)); } - float duration_secs = (float)best_duration/cpu_hz; - // printf("duration: %f, err:%f", duration_secs, TIME_PER_FRAME - duration_secs); - - int new_boid_count; - float diff = TIME_PER_FRAME - duration_secs; - if (diff < 0) { - if (prev_boid_count < boid_count) { - new_boid_count = (prev_boid_count + boid_count)/2; - } else { - new_boid_count = boid_count/2; - } - } else if (diff > 0) { - if (prev_boid_count > boid_count) { - new_boid_count = (prev_boid_count + boid_count)/2; - } else { - new_boid_count = boid_count*2; - } - } - - prev_boid_count = boid_count; - boid_count = new_boid_count; - } while (std::abs(boid_count - prev_boid_count) > 10); - - return boid_count; -} - -int foo_main() { - rprof_init(); - - world_init(&g_world, 1280, 720); - - float border = g_visuals.boid_edge_size; - for (int i = 0; i < 50000; i++) { - Boid boid; - boid_rand_init(&g_world, &boid, border); - g_world.boids.push_back(boid); + printf("arena: %ld (%.03fMiB)\n", g_world.frame_arena.offset, (float)g_world.frame_arena.offset / 1024 / 1024); + world_free(&g_world); } - - for (int i = 0; i < 1; i++) { - world_update(&g_world, TIME_PER_FRAME); - } - - printf("arena: %ld (%.03fMiB)\n", g_world.frame_arena.offset, (float)g_world.frame_arena.offset / 1024 / 1024); - world_free(&g_world); - rprof_end(); rprof_output(NULL); - - return 0; } int main() {