From 1ea79e8626740dd43b9ab1cbf389b86a1e5f9e72 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 17 Mar 2013 16:37:27 +0900 Subject: [PATCH] Allocate stack blocks and mightsee in one block. This bypasses set_new, but completely removes the use of the global lock from within RecursiveClusterFlow. This seems to give a small speedup: 203 seconds threaded. --- tools/qfvis/include/vis.h | 4 ++-- tools/qfvis/source/flow.c | 42 ++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tools/qfvis/include/vis.h b/tools/qfvis/include/vis.h index b4a29ab4f..8c5c1b22d 100644 --- a/tools/qfvis/include/vis.h +++ b/tools/qfvis/include/vis.h @@ -102,8 +102,8 @@ typedef struct pstack_s { portal_t *portal; // portal exiting winding_t *source, *pass; plane_t portalplane; - set_t *mightsee; sep_t *separators[2]; + set_t mightsee; } pstack_t; typedef struct { @@ -126,7 +126,7 @@ typedef struct threaddata_s { visstat_t stats; ///< per-thread statistics merged on completion set_t *clustervis; ///< clusters base portal can see portal_t *base; ///< portal for which this thread is being run - pstack_t pstack_head; + pstack_t *pstack_head; sep_t *sep_freelist; ///< per-thread list of free separators } threaddata_t; diff --git a/tools/qfvis/source/flow.c b/tools/qfvis/source/flow.c index 732351aa6..ae94c9b1d 100644 --- a/tools/qfvis/source/flow.c +++ b/tools/qfvis/source/flow.c @@ -63,7 +63,7 @@ CheckStack (cluster_t *cluster, threaddata_t *thread) { pstack_t *portal; - for (portal = thread->pstack_head.next; portal; portal = portal->next) { + for (portal = thread->pstack_head->next; portal; portal = portal->next) { if (portal->cluster == cluster) { printf ("CheckStack: cluster recursion\n"); return 1; @@ -78,12 +78,12 @@ static pstack_t * new_stack (void) { pstack_t *stack; + unsigned size = SET_SIZE (portalclusters - 1); - stack = malloc (sizeof (pstack_t)); - stack->next = 0; - LOCK; - stack->mightsee = set_new_size (portalclusters); - UNLOCK; + stack = calloc (1, field_offset (pstack_t, + mightsee.defmap[size / SET_BITS])); + stack->mightsee.size = size; + stack->mightsee.map = stack->mightsee.defmap; return stack; } @@ -301,19 +301,19 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack) stack->portal = NULL; stack->separators[0] = 0; stack->separators[1] = 0; - might = stack->mightsee; + might = &stack->mightsee; vis = thread->clustervis; // check all portals for flowing into other clusters for (i = 0; i < cluster->numportals; i++) { portal = cluster->portals[i]; - if (!set_is_member (prevstack->mightsee, portal->cluster)) + if (!set_is_member (&prevstack->mightsee, portal->cluster)) continue; // can't possibly see it // if the portal can't see anything we haven't already seen, skip it test = select_test_set (portal, thread); - if (!mightsee_more (might, prevstack->mightsee, test, vis)) { + if (!mightsee_more (might, &prevstack->mightsee, test, vis)) { // can't see anything new continue; } @@ -331,7 +331,7 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack) stack->portal = portal; target = ClipWinding (portal->winding, - &thread->pstack_head.portalplane, false); + &thread->pstack_head->portalplane, false); if (!target) continue; @@ -367,7 +367,7 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack) winding_t *old = target; if (!stack->separators[0]) stack->separators[0] = FindSeparators (thread, source, - thread->pstack_head.portalplane, + thread->pstack_head->portalplane, prevstack->pass, 0); target = ClipToSeparators (stack->separators[0], target); if (!target) { @@ -464,14 +464,16 @@ PortalFlow (threaddata_t *data, portal_t *portal) data->clustervis = portal->visbits; data->base = portal; - data->pstack_head.cluster = 0; - data->pstack_head.portal = portal; - data->pstack_head.source = portal->winding; - data->pstack_head.pass = 0; - data->pstack_head.portalplane = portal->plane; - data->pstack_head.mightsee = portal->mightsee; - data->pstack_head.separators[0] = 0; - data->pstack_head.separators[1] = 0; + if (!data->pstack_head) + data->pstack_head = new_stack (); + data->pstack_head->cluster = 0; + data->pstack_head->portal = portal; + data->pstack_head->source = portal->winding; + data->pstack_head->pass = 0; + data->pstack_head->portalplane = portal->plane; + set_assign (&data->pstack_head->mightsee, portal->mightsee); + data->pstack_head->separators[0] = 0; + data->pstack_head->separators[1] = 0; - RecursiveClusterFlow (portal->cluster, data, &data->pstack_head); + RecursiveClusterFlow (portal->cluster, data, data->pstack_head); }