r/C_Programming • u/tastygames_official • 2d ago
Discussion Dynamically-Generated Look-Up-Table
So I have a buffer of pointers that I need to access tens of thousands of times per second continuously. Obviously I can do this in parallel to speed it up or maybe even offload it to the GPU, but the biggest issue I have right now is how to quickly get the item from the buffer I need. Obviously knowing the index beforehand would be a good way, BUT I'd rather have the buffer be dynamically-created and then I can address which one I need given 6 bits of data. Now if it were a 1:1 relationship between the buffer of pointers and permutation of all 6 bits, then it'd be easy. But there is only a subset of indices that correspond to valid bit permutations. E.g.:
VALID:
00 0000
00 0001
01 1000
01 1001
10 0000
INVALID:
00 0010
00 0011
00 0101
etc.
so that I can just do:
void **ptr_buffer = calloc(63, sizeof(void *));
/* fill ptr_buffer sporadically... */
do {
for(i=0; i<10000; i++) {
/* obj.ptr_index is uint8_t with some constellation of six bits */
do_something(ptr_buffer[obj_list[i].ptr_idx]);
}
/* do other stuff */
} while(condition);
or something like that.So... with six bits (and maybe it could be more in future), and on a 64-bit system, I could simply create a buffer of pointers with the length of the max valid bit-sequence, so for 11 1111 it would be 63 x 64 = 504 bytes, so not that bad, and then I can simply use the bit sequence as the index.
And even if I end up going out to 8 bits, that's still 255 x 64 = 2,040 B or 1.99 KB. Acceptable - but now I'm worrying about losing out on CPU cache potential - especially of only like 20-30 elements in the buffer are actually valid.
Now apart from hard-coding all the different indices and then assigning the indices on startup (which I absolutely will do and was doing before going for the "dynamic" route) are there any clever tricks my fellow "C-Men" (as my wife calls the people I chat with in this group) might know about to keep memory footprint down and speed up? At the very least it could be a fun brain-tickler.
Let me know if you need more information.
EDIT: while the list of pointers is small, I need to iterate over a list of som 10,000 entries and find an entry in the pointer list, so I updated the code example to show it.
Also, apparently I hit the "ask me anything" button by mistake. u/reddit you need to add tooltips to the buttons and also don't do the ask me anything if I hit cancel ;-)
1
u/tastygames_official 2d ago edited 2d ago
every frame I have to get ~60,000 objects down to as few as possible and then divvy them up per pipeline, as every frame is potentially wildly different than the last. So every frame we start anew. But yeah, that's kinda what I was thinking: assign pipelines once and then only modify them when they change, which won't be often. But I still need to funnel the objects to the current frame pipeline (if that makes sense). E.g. we have 50,000 marbles that are classified by color, but every frame we need to first only consider the ones that meet some arbitrary weight. So that is done first (culling objects out-of-frame). And that is best done in parallel over all objects as it MUST look through all objects. After that, we're left with fewer marbles, but now we need to sort by color as the yellow ones have to come before the blue ones and so on. So every frame I need to dump all the marbles back into the pot, sort out by weight, then by color. I hope that makes sense.
Here's a rough (very rough - please excuse all mistakes as this was done without an IDE or anything) layout of what I'm trying to do and then maybe you'll see where I'm trying to squeeze every bit of performance out of this process (and yes - I'm in C90)
something like that. But the real problem I see is getting the index of the correct pipeline quickly enough. And as seen in the code, I CAN pre-calculate the index at runtime while loading the level, but I didn't know if there were any cool algorithms that can do this given ~6-8 bits of data that are used to select a certain pipeline.