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.
This commit is contained in:
Bill Currie 2013-03-17 16:37:27 +09:00
parent 1d262f7dea
commit 1ea79e8626
2 changed files with 24 additions and 22 deletions

View file

@ -102,8 +102,8 @@ typedef struct pstack_s {
portal_t *portal; // portal exiting portal_t *portal; // portal exiting
winding_t *source, *pass; winding_t *source, *pass;
plane_t portalplane; plane_t portalplane;
set_t *mightsee;
sep_t *separators[2]; sep_t *separators[2];
set_t mightsee;
} pstack_t; } pstack_t;
typedef struct { typedef struct {
@ -126,7 +126,7 @@ typedef struct threaddata_s {
visstat_t stats; ///< per-thread statistics merged on completion visstat_t stats; ///< per-thread statistics merged on completion
set_t *clustervis; ///< clusters base portal can see set_t *clustervis; ///< clusters base portal can see
portal_t *base; ///< portal for which this thread is being run 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 sep_t *sep_freelist; ///< per-thread list of free separators
} threaddata_t; } threaddata_t;

View file

@ -63,7 +63,7 @@ CheckStack (cluster_t *cluster, threaddata_t *thread)
{ {
pstack_t *portal; 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) { if (portal->cluster == cluster) {
printf ("CheckStack: cluster recursion\n"); printf ("CheckStack: cluster recursion\n");
return 1; return 1;
@ -78,12 +78,12 @@ static pstack_t *
new_stack (void) new_stack (void)
{ {
pstack_t *stack; pstack_t *stack;
unsigned size = SET_SIZE (portalclusters - 1);
stack = malloc (sizeof (pstack_t)); stack = calloc (1, field_offset (pstack_t,
stack->next = 0; mightsee.defmap[size / SET_BITS]));
LOCK; stack->mightsee.size = size;
stack->mightsee = set_new_size (portalclusters); stack->mightsee.map = stack->mightsee.defmap;
UNLOCK;
return stack; return stack;
} }
@ -301,19 +301,19 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
stack->portal = NULL; stack->portal = NULL;
stack->separators[0] = 0; stack->separators[0] = 0;
stack->separators[1] = 0; stack->separators[1] = 0;
might = stack->mightsee; might = &stack->mightsee;
vis = thread->clustervis; vis = thread->clustervis;
// check all portals for flowing into other clusters // check all portals for flowing into other clusters
for (i = 0; i < cluster->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = cluster->portals[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 continue; // can't possibly see it
// if the portal can't see anything we haven't already seen, skip it // if the portal can't see anything we haven't already seen, skip it
test = select_test_set (portal, thread); 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 // can't see anything new
continue; continue;
} }
@ -331,7 +331,7 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
stack->portal = portal; stack->portal = portal;
target = ClipWinding (portal->winding, target = ClipWinding (portal->winding,
&thread->pstack_head.portalplane, false); &thread->pstack_head->portalplane, false);
if (!target) if (!target)
continue; continue;
@ -367,7 +367,7 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
winding_t *old = target; winding_t *old = target;
if (!stack->separators[0]) if (!stack->separators[0])
stack->separators[0] = FindSeparators (thread, source, stack->separators[0] = FindSeparators (thread, source,
thread->pstack_head.portalplane, thread->pstack_head->portalplane,
prevstack->pass, 0); prevstack->pass, 0);
target = ClipToSeparators (stack->separators[0], target); target = ClipToSeparators (stack->separators[0], target);
if (!target) { if (!target) {
@ -464,14 +464,16 @@ PortalFlow (threaddata_t *data, portal_t *portal)
data->clustervis = portal->visbits; data->clustervis = portal->visbits;
data->base = portal; data->base = portal;
data->pstack_head.cluster = 0; if (!data->pstack_head)
data->pstack_head.portal = portal; data->pstack_head = new_stack ();
data->pstack_head.source = portal->winding; data->pstack_head->cluster = 0;
data->pstack_head.pass = 0; data->pstack_head->portal = portal;
data->pstack_head.portalplane = portal->plane; data->pstack_head->source = portal->winding;
data->pstack_head.mightsee = portal->mightsee; data->pstack_head->pass = 0;
data->pstack_head.separators[0] = 0; data->pstack_head->portalplane = portal->plane;
data->pstack_head.separators[1] = 0; 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);
} }