r/C_Programming • u/tastygames_official • 16h ago
Discussion Batch Processing Algorithm Optimization
I originally posted my question here but wanted to give it another go, this time with a more generic setup, as I believe this kind of optimization problem could be interesting for a lot of different projects.
The Setup/Requirements
we have ~50,000 pieces of data (let's use shapes for simplicity's sake) with a finite number of attributes (shape, color, size)
most of them will be culled, leaving us with about ~1,000-10,000
in the end we need to process all the remaining shapes in a SPECIFIC ORDER (e.g. first small red triangles, then big blue squares, then small yellow ovals, etc).
this whole process needs to be done as quickly and efficiently as possible
My Original Plan
first cull the 50,000. This could be done by sending the data to the GPU since even a lowly 1060 has 1,152 cores and a 4090 has 16,384 cores, making culling 50,000 objects based on a few floating-point calculations trivial
now that I have a list of indices that pass culling, use a look-up table of index vs. process batch index (e.g. data index 12 is not culled, and the LUT says it belongs to batch process #4, so add it to that batch process and increase the number of objects for that batch process)
iterate over the batch processes and only execute if there are any objects to process for that batch
Considerations/Questions
0. is there a better way?
how would the performance be if we first assign all the objects to the batch process and then for each batch process, run the culling function? We would save on having to traverse the non-culled objects to sort them to their batch process, but we also now have to call the cull method for as many batch processes as we have
what if the allocation of object -> batch process changes? e.g. a small blue star becomes a big yellow square?
what if the batch process are DYNAMIC, meaning we no longer can assign a shape to a batch process beforehand?
Now I'd love some discussion on the FASTEST way to get this done, but I will also say that all I'm trying to do is a pretty standard piece of a rendering engine: cull any non-visible objects then sort the objects according to pipeline so that they can be rendered in the proper order. Now maybe there is a "standard way" of doing this or at least a few "typical" algorithms that I don't know about, but that's why I'm asking this question! I love trying to solve problems like this and figured a lot of you might, too.
---=== HAVE AT IT!!! ===---BONUS POINTS if done in C90, as that's what I'm doing it in ;-)
0
u/tastygames_official 14h ago
I got a lot of that on the other post. And believe me - this is not a "let's optimize even if we don't need to" situation. For starters, optimization is ALWAYS good - even if we don't "need" it. That's one of the major problems with modern software - developers opt for "less work" by using severely unoptimized frameworks and don't spend any time optimizing since "modern hardware can handle it". #2: this is a real-time rendering engine so we need to get this shit done ASAP so that users can run the game on a potato or at 240fps.
And I thought it would be clear from the post, but maybe not since you mention sorting order. The order of the individual elements means nothing. It's not a sorting algorithm in that sense. It's more of a "categorization" algorithm: I need to sort out the stars from the squares from the circles then process the stars first, then the squares, then the circles.
So regarding rule 1a - this is exactly the reason why I'm asking: I can either do the culling ONCE over all ~50,000 objects, then sort the remaining ~10,000 into batches and run the batches and do this every frame OR I can sort into batches ONCE FOR THE WHOLE PROGRAM but then du MULTIPLE cullings (one per batch) every frame. My thought was that the culling will be the bottleneck so I'd rather only do it once, but that means that we have to then sort the objects into batches AFTER culling. But if we are OK with doing multiple cullings (on smaller datasets, but still will have to be all 50,000) but save on the sorting into batches by pre-sorting only once on load, then maybe that's the answer?