From 5d6df082f2322d8e1373865344fba3d510232a8c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 14 Mar 2013 11:33:47 +0900 Subject: [PATCH] Move the vis stats vars into thread data. This should make the stats more reliable when running multi-threaded (chains is still random, but it seems there are set access issues). --- tools/qfvis/include/vis.h | 20 ++++++++++++-------- tools/qfvis/source/flow.c | 34 ++++++++++++++++------------------ tools/qfvis/source/qfvis.c | 34 ++++++++++++++++++++-------------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/tools/qfvis/include/vis.h b/tools/qfvis/include/vis.h index 0e88432b3..7282fc070 100644 --- a/tools/qfvis/include/vis.h +++ b/tools/qfvis/include/vis.h @@ -107,7 +107,18 @@ typedef struct pstack_s { sep_t *separators[2]; } pstack_t; +typedef struct { + int portaltest; + int portalpass; + int portalcheck; + int chains; + int mighttest; + int vistest; + int mightseeupdate; +} visstat_t; + typedef struct threaddata_s { + visstat_t stats; set_t *clustervis; portal_t *base; pstack_t pstack_head; @@ -117,9 +128,6 @@ typedef struct threaddata_s { extern int numportals; extern int portalclusters; extern int numrealleafs; -extern int c_portaltest; -extern int c_portalpass; -extern int c_portalcheck; extern int bitbytes; extern int bitbytes_l; extern int bitlongs; @@ -130,10 +138,6 @@ extern cluster_t *clusters; extern int *leafcluster; extern byte *uncompressed; -extern int c_chains; -extern int c_mighttest; -extern int c_vistest; - void FreeWinding (winding_t *w); winding_t *NewWinding (int points); winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon); @@ -141,7 +145,7 @@ winding_t *CopyWinding (winding_t *w); void ClusterFlow (int clusternum); void BasePortalVis (void); -void PortalFlow (portal_t *portal); +void PortalFlow (threaddata_t *data, portal_t *portal); void CalcAmbientSounds (void); #endif// __vis_h diff --git a/tools/qfvis/source/flow.c b/tools/qfvis/source/flow.c index cc0d6cd60..82aef4428 100644 --- a/tools/qfvis/source/flow.c +++ b/tools/qfvis/source/flow.c @@ -254,7 +254,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) plane_t backplane; winding_t *source, *target; - c_chains++; + thread->stats.chains++; cluster = &clusters[clusternum]; if (CheckStack(cluster, thread)) @@ -287,10 +287,10 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) continue; // can't possibly see it // if the portal can't see anything we haven't already seen, skip it if (portal->status == stat_done) { - c_vistest++; + thread->stats.vistest++; test = portal->visbits; } else { - c_mighttest++; + thread->stats.mighttest++; test = portal->mightsee; } set_assign (might, prevstack->mightsee); @@ -308,7 +308,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) if (_VectorCompare (prevstack->portalplane.normal, backplane.normal)) continue; // can't go out a coplanar face - c_portalcheck++; + thread->stats.portalcheck++; stack.portal = portal; stack.next = NULL; @@ -340,7 +340,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) continue; } - c_portaltest++; + thread->stats.portaltest++; if (options.level > 0) { // clip target to the image that would be formed by a laser @@ -392,7 +392,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) stack.source = source; stack.pass = target; - c_portalpass++; + thread->stats.portalpass++; // flow through it for real RecursiveClusterFlow (portal->cluster, &stack); @@ -408,10 +408,8 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack) } void -PortalFlow (portal_t *portal) +PortalFlow (threaddata_t *data, portal_t *portal) { - threaddata_t data; - LOCK; if (portal->status != stat_selected) Sys_Error ("PortalFlow: reflowed"); @@ -419,15 +417,15 @@ PortalFlow (portal_t *portal) portal->visbits = set_new_size (portalclusters); UNLOCK; - memset (&data, 0, sizeof (data)); - data.clustervis = portal->visbits; - data.base = portal; + data->clustervis = portal->visbits; + data->base = portal; - data.pstack_head.thread = &data; - data.pstack_head.portal = portal; - data.pstack_head.source = portal->winding; - data.pstack_head.portalplane = portal->plane; - data.pstack_head.mightsee = portal->mightsee; + memset (&data->pstack_head, 0, sizeof (data->pstack_head)); + data->pstack_head.thread = data; + data->pstack_head.portal = portal; + data->pstack_head.source = portal->winding; + data->pstack_head.portalplane = portal->plane; + data->pstack_head.mightsee = portal->mightsee; - RecursiveClusterFlow (portal->cluster, &data.pstack_head); + RecursiveClusterFlow (portal->cluster, &data->pstack_head); } diff --git a/tools/qfvis/source/qfvis.c b/tools/qfvis/source/qfvis.c index 5e23d1c47..4e71dae58 100644 --- a/tools/qfvis/source/qfvis.c +++ b/tools/qfvis/source/qfvis.c @@ -70,13 +70,7 @@ bsp_t *bsp; options_t options; -int c_chains; -int c_mighttest; -int c_portaltest; -int c_portalpass; -int c_portalcheck; -int c_vistest; -int c_mightseeupdate; +static visstat_t stats; int portal_count; int numportals; @@ -293,13 +287,13 @@ UpdateMightsee (cluster_t *source, cluster_t *dest) if (set_is_member (portal->mightsee, clusternum)) { set_remove (portal->mightsee, clusternum); portal->nummightsee--; - c_mightseeupdate++; + stats.mightseeupdate++; } } } static void -PortalCompleted (portal_t *completed) +PortalCompleted (threaddata_t *thread, portal_t *completed) { portal_t *portal; cluster_t *cluster; @@ -309,6 +303,15 @@ PortalCompleted (portal_t *completed) completed->status = stat_done; LOCK; + stats.portaltest += thread->stats.portaltest; + stats.portalpass += thread->stats.portalpass; + stats.portalcheck += thread->stats.portalcheck; + stats.chains += thread->stats.chains; + stats.mighttest += thread->stats.mighttest; + stats.vistest += thread->stats.vistest; + stats.mightseeupdate += thread->stats.mightseeupdate; + memset (&thread->stats, 0, sizeof (thread->stats)); + changed = set_new_size (portalclusters); cluster = &clusters[completed->cluster]; for (i = 0; i < cluster->numportals; i++) { @@ -338,7 +341,9 @@ LeafThread (void *_thread) { portal_t *portal; int thread = (int) (intptr_t) _thread; + threaddata_t data; + memset (&data, 0, sizeof (data)); do { portal = GetNextPortal (); if (!portal) @@ -346,9 +351,10 @@ LeafThread (void *_thread) if (working) working[thread] = (int) (portal - portals); - PortalFlow (portal); - PortalCompleted (portal); + PortalFlow (&data, portal); + + PortalCompleted (&data, portal); if (options.verbosity > 1) printf ("portal:%5i mightsee:%5i cansee:%5i %5d/%d\n", @@ -555,8 +561,8 @@ CalcPortalVis (void) if (options.verbosity > 0) { printf ("portalcheck: %i portaltest: %i portalpass: %i\n", - c_portalcheck, c_portaltest, c_portalpass); - printf ("c_vistest: %i c_mighttest: %i c_mightseeupdate: %i\n", c_vistest, c_mighttest, c_mightseeupdate); + stats.portalcheck, stats.portaltest, stats.portalpass); + printf ("vistest: %i mighttest: %i mightseeupdate: %i\n", stats.vistest, stats.mighttest, stats.mightseeupdate); } } @@ -968,7 +974,7 @@ main (int argc, char **argv) CalcVis (); if (options.verbosity >= 0) - printf ("c_chains: %i%s\n", c_chains, + printf ("chains: %i%s\n", stats.chains, options.threads > 1 ? " (not reliable)" :""); BSP_AddVisibility (bsp, (byte *) visdata->str, visdata->size);