Last active
November 12, 2025 09:13
-
-
Save memononen/c4944a6815fd4c60381f5fe91d109b17 to your computer and use it in GitHub Desktop.
Process entities
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// | |
| static inline int32_t mot_bitset_next(uint64_t* bitset) | |
| { | |
| const int32_t idx = (int32_t)mot_tzcnt64(*bitset); // trailing zero count | |
| *bitset &= (*bitset - 1); // clear lsb | |
| return idx; | |
| } | |
| typedef struct pos_comp_t { | |
| mot_vec2_t pos; | |
| } pos_comp_t; | |
| typedef struct move_comp_t { | |
| mot_vec2_t dir; | |
| float speed; | |
| } move_comp_t; | |
| // | |
| // Simple loop | |
| // | |
| void test_loop(int32_t iters, int32_t count, float dt) | |
| { | |
| pos_comp_t* pos_comps = mot_malloc(count * sizeof(pos_comp_t)); | |
| move_comp_t* move_comps = mot_malloc(count * sizeof(move_comp_t)); | |
| for (int32_t i = 0; i < count; i++) | |
| init_pos_comp(&pos_comps[i]); | |
| for (int32_t i = 0; i < count; i++) | |
| init_move_comp(&move_comps[i]); | |
| const int64_t t0 = mot_perf_timer_get(); | |
| for (int32_t it = 0; it < iters; it++) { | |
| pos_comp_t* pos = pos_comps; | |
| move_comp_t* move = move_comps; | |
| int32_t n = count; | |
| while (n--) { | |
| pos->pos = mot_vec2_mad(pos->pos, move->dir, move->speed * dt); | |
| pos++; | |
| move++; | |
| } | |
| } | |
| const int64_t t1 = mot_perf_timer_get(); | |
| mot_debug_log("test_loop %d x %d: %d us\n", iters, count, mot_perf_timer_elapsed_us(t0,t1)); | |
| mot_free(pos_comps); | |
| mot_free(move_comps); | |
| } | |
| // | |
| // Enabled flags + function ptr | |
| // | |
| typedef void process_func_sparse_t(uint64_t bitset, uint8_t** data, int32_t data_count, float dt); | |
| void process_chunk_sparse(uint64_t bitset, uint8_t** data, int32_t data_count, float dt) | |
| { | |
| pos_comp_t* pos = (pos_comp_t*)data[0]; | |
| move_comp_t* move = (move_comp_t*)data[1]; | |
| while (bitset) { | |
| const int32_t i = mot_bitset_next(&bitset); | |
| pos[i].pos = mot_vec2_mad(pos[i].pos, move[i].dir, move[i].speed * dt); | |
| } | |
| } | |
| void process_sparse(const uint64_t* enabled_bitset, uint8_t** data, const int32_t* data_stride, int32_t data_count, int32_t elem_count, float dt, process_func_sparse_t* func) | |
| { | |
| int32_t chunk_count = (elem_count+63) / 64; | |
| uint8_t* chunk_data[8]; | |
| for (int32_t di = 0; di < data_count; di++) | |
| chunk_data[di] = data[di]; | |
| for (int32_t i = 0; i < chunk_count; i++) { | |
| // Process 64 items | |
| uint64_t bitset = enabled_bitset[i]; | |
| func(bitset, chunk_data, data_count, dt); | |
| // Advance to next chunk | |
| for (int32_t di = 0; di < data_count; di++) | |
| chunk_data[di] += data_stride[di]; | |
| } | |
| } | |
| void test_loop_func_sparse(int32_t iters, int32_t count, int32_t enabled_count, float dt) | |
| { | |
| assert(enabled_count <= count); | |
| pos_comp_t* pos_comps = mot_malloc(count * sizeof(pos_comp_t)); | |
| move_comp_t* move_comps = mot_malloc(count * sizeof(move_comp_t)); | |
| int32_t enabled_bitset_count = (count+63)/64; | |
| uint64_t* enabled_bitset = mot_malloc(enabled_bitset_count * sizeof(uint64_t)); | |
| memset(enabled_bitset, 0, enabled_bitset_count * sizeof(uint64_t)); | |
| enable_random(enabled_bitset, enabled_bitset_count, count, enabled_count); | |
| for (int32_t i = 0; i < count; i++) | |
| init_pos_comp(&pos_comps[i]); | |
| for (int32_t i = 0; i < count; i++) | |
| init_move_comp(&move_comps[i]); | |
| const int64_t t0 = mot_perf_timer_get(); | |
| for (int32_t it = 0; it < iters; it++) { | |
| uint8_t* data[2] = { (uint8_t*)pos_comps, (uint8_t*)move_comps }; | |
| const int32_t data_stride[2] = { sizeof(pos_comp_t) * 64, sizeof(move_comp_t) * 64 }; | |
| process_sparse(enabled_bitset, data, data_stride, 2, count, dt, process_chunk_sparse); | |
| } | |
| const int64_t t1 = mot_perf_timer_get(); | |
| mot_debug_log("test_loop_func_sparse %d x %d (%d, %.1f%%): %d us\n", iters, count, enabled_count, (float)enabled_count/(float)count*100.f, mot_perf_timer_elapsed_us(t0,t1)); | |
| mot_free(pos_comps); | |
| mot_free(move_comps); | |
| mot_free(enabled_bitset); | |
| } | |
| // |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment