~33% speed improvement on vis by using already-allocated memory for the vis stack

This commit is contained in:
Jonathan 2022-06-17 13:53:35 -04:00
parent 46aaa81ffd
commit c3bb07acaa
3 changed files with 20 additions and 10 deletions

View File

@ -150,14 +150,15 @@ struct pstack_t
leaf_t *leaf; leaf_t *leaf;
portal_t *portal; // portal exiting portal_t *portal; // portal exiting
std::shared_ptr<winding_t> source, pass; std::shared_ptr<winding_t> source, pass;
std::shared_ptr<winding_t> windings[STACK_WINDINGS]; // Fixed size windings winding_t windings[STACK_WINDINGS]; // Fixed size windings
bool windings_used[STACK_WINDINGS]; // whether the winding is used currently
qplane3d portalplane; qplane3d portalplane;
leafbits_t *mightsee; // bit string leafbits_t *mightsee; // bit string
qplane3d separators[2][MAX_SEPARATORS]; /* Separator cache */ qplane3d separators[2][MAX_SEPARATORS]; /* Separator cache */
int numseparators[2]; int numseparators[2];
}; };
std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack); std::shared_ptr<winding_t> AllocStackWinding(pstack_t *stack);
void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack); void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack);
std::shared_ptr<winding_t> ClipStackWinding(std::shared_ptr<winding_t> &in, pstack_t *stack, qplane3d *split); std::shared_ptr<winding_t> ClipStackWinding(std::shared_ptr<winding_t> &in, pstack_t *stack, qplane3d *split);

View File

@ -179,7 +179,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs
stack.numseparators[1] = 0; stack.numseparators[1] = 0;
for (i = 0; i < STACK_WINDINGS; i++) for (i = 0; i < STACK_WINDINGS; i++)
stack.windings[i].reset(); stack.windings_used[i] = false;
leafbits_t local(portalleafs); leafbits_t local(portalleafs);
stack.mightsee = &local; stack.mightsee = &local;

View File

@ -63,6 +63,10 @@ void vis_settings::initialize(int argc, const char **argv)
settings::vis_settings options; settings::vis_settings options;
fs::path portalfile, statefile, statetmpfile; fs::path portalfile, statefile, statetmpfile;
struct noop_delete {
void operator()(winding_t *p) const { }
};
/* /*
================== ==================
@ -71,11 +75,14 @@ fs::path portalfile, statefile, statetmpfile;
Return a pointer to a free fixed winding on the stack Return a pointer to a free fixed winding on the stack
================== ==================
*/ */
std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack) std::shared_ptr<winding_t> AllocStackWinding(pstack_t *stack)
{ {
for (auto &winding : stack->windings) { for (size_t i = 0; i < STACK_WINDINGS; i++) {
if (!winding) { if (!stack->windings_used[i]) {
return (winding = std::make_shared<winding_t>()); stack->windings_used[i] = true;
return std::shared_ptr<winding_t>(&stack->windings[i], [stack, i]([[maybe_unused]] winding_t *) {
stack->windings_used[i] = false;
});
} }
} }
@ -89,14 +96,16 @@ std::shared_ptr<winding_t> &AllocStackWinding(pstack_t *stack)
As long as the winding passed in is local to the stack, free it. Otherwise, As long as the winding passed in is local to the stack, free it. Otherwise,
do nothing (the winding either belongs to a portal or another stack do nothing (the winding either belongs to a portal or another stack
structure further up the call chain). structure further up the call chain).
FIXME: is there some way we can refactor this out entirely? the deleter
for stack windings is safe
================== ==================
*/ */
void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack) void FreeStackWinding(std::shared_ptr<winding_t> &w, pstack_t *stack)
{ {
for (auto &winding : stack->windings) { for (size_t i = 0; i < STACK_WINDINGS; i++) {
if (winding == w) { if (stack->windings_used[i] && &stack->windings[i] == w.get()) {
w.reset(); w.reset();
winding.reset();
return; return;
} }
} }