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).
This commit is contained in:
Bill Currie 2013-03-14 11:33:47 +09:00
parent 0cae04d71a
commit 5d6df082f2
3 changed files with 48 additions and 40 deletions

View file

@ -107,7 +107,18 @@ typedef struct pstack_s {
sep_t *separators[2]; sep_t *separators[2];
} pstack_t; } pstack_t;
typedef struct {
int portaltest;
int portalpass;
int portalcheck;
int chains;
int mighttest;
int vistest;
int mightseeupdate;
} visstat_t;
typedef struct threaddata_s { typedef struct threaddata_s {
visstat_t stats;
set_t *clustervis; set_t *clustervis;
portal_t *base; portal_t *base;
pstack_t pstack_head; pstack_t pstack_head;
@ -117,9 +128,6 @@ typedef struct threaddata_s {
extern int numportals; extern int numportals;
extern int portalclusters; extern int portalclusters;
extern int numrealleafs; extern int numrealleafs;
extern int c_portaltest;
extern int c_portalpass;
extern int c_portalcheck;
extern int bitbytes; extern int bitbytes;
extern int bitbytes_l; extern int bitbytes_l;
extern int bitlongs; extern int bitlongs;
@ -130,10 +138,6 @@ extern cluster_t *clusters;
extern int *leafcluster; extern int *leafcluster;
extern byte *uncompressed; extern byte *uncompressed;
extern int c_chains;
extern int c_mighttest;
extern int c_vistest;
void FreeWinding (winding_t *w); void FreeWinding (winding_t *w);
winding_t *NewWinding (int points); winding_t *NewWinding (int points);
winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon); 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 ClusterFlow (int clusternum);
void BasePortalVis (void); void BasePortalVis (void);
void PortalFlow (portal_t *portal); void PortalFlow (threaddata_t *data, portal_t *portal);
void CalcAmbientSounds (void); void CalcAmbientSounds (void);
#endif// __vis_h #endif// __vis_h

View file

@ -254,7 +254,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack)
plane_t backplane; plane_t backplane;
winding_t *source, *target; winding_t *source, *target;
c_chains++; thread->stats.chains++;
cluster = &clusters[clusternum]; cluster = &clusters[clusternum];
if (CheckStack(cluster, thread)) if (CheckStack(cluster, thread))
@ -287,10 +287,10 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack)
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
if (portal->status == stat_done) { if (portal->status == stat_done) {
c_vistest++; thread->stats.vistest++;
test = portal->visbits; test = portal->visbits;
} else { } else {
c_mighttest++; thread->stats.mighttest++;
test = portal->mightsee; test = portal->mightsee;
} }
set_assign (might, prevstack->mightsee); set_assign (might, prevstack->mightsee);
@ -308,7 +308,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack)
if (_VectorCompare (prevstack->portalplane.normal, backplane.normal)) if (_VectorCompare (prevstack->portalplane.normal, backplane.normal))
continue; // can't go out a coplanar face continue; // can't go out a coplanar face
c_portalcheck++; thread->stats.portalcheck++;
stack.portal = portal; stack.portal = portal;
stack.next = NULL; stack.next = NULL;
@ -340,7 +340,7 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack)
continue; continue;
} }
c_portaltest++; thread->stats.portaltest++;
if (options.level > 0) { if (options.level > 0) {
// clip target to the image that would be formed by a laser // 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.source = source;
stack.pass = target; stack.pass = target;
c_portalpass++; thread->stats.portalpass++;
// flow through it for real // flow through it for real
RecursiveClusterFlow (portal->cluster, &stack); RecursiveClusterFlow (portal->cluster, &stack);
@ -408,10 +408,8 @@ RecursiveClusterFlow (int clusternum, pstack_t *prevstack)
} }
void void
PortalFlow (portal_t *portal) PortalFlow (threaddata_t *data, portal_t *portal)
{ {
threaddata_t data;
LOCK; LOCK;
if (portal->status != stat_selected) if (portal->status != stat_selected)
Sys_Error ("PortalFlow: reflowed"); Sys_Error ("PortalFlow: reflowed");
@ -419,15 +417,15 @@ PortalFlow (portal_t *portal)
portal->visbits = set_new_size (portalclusters); portal->visbits = set_new_size (portalclusters);
UNLOCK; UNLOCK;
memset (&data, 0, sizeof (data)); data->clustervis = portal->visbits;
data.clustervis = portal->visbits; data->base = portal;
data.base = portal;
data.pstack_head.thread = &data; memset (&data->pstack_head, 0, sizeof (data->pstack_head));
data.pstack_head.portal = portal; data->pstack_head.thread = data;
data.pstack_head.source = portal->winding; 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.portalplane = portal->plane;
data->pstack_head.mightsee = portal->mightsee;
RecursiveClusterFlow (portal->cluster, &data.pstack_head); RecursiveClusterFlow (portal->cluster, &data->pstack_head);
} }

View file

@ -70,13 +70,7 @@ bsp_t *bsp;
options_t options; options_t options;
int c_chains; static visstat_t stats;
int c_mighttest;
int c_portaltest;
int c_portalpass;
int c_portalcheck;
int c_vistest;
int c_mightseeupdate;
int portal_count; int portal_count;
int numportals; int numportals;
@ -293,13 +287,13 @@ UpdateMightsee (cluster_t *source, cluster_t *dest)
if (set_is_member (portal->mightsee, clusternum)) { if (set_is_member (portal->mightsee, clusternum)) {
set_remove (portal->mightsee, clusternum); set_remove (portal->mightsee, clusternum);
portal->nummightsee--; portal->nummightsee--;
c_mightseeupdate++; stats.mightseeupdate++;
} }
} }
} }
static void static void
PortalCompleted (portal_t *completed) PortalCompleted (threaddata_t *thread, portal_t *completed)
{ {
portal_t *portal; portal_t *portal;
cluster_t *cluster; cluster_t *cluster;
@ -309,6 +303,15 @@ PortalCompleted (portal_t *completed)
completed->status = stat_done; completed->status = stat_done;
LOCK; 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); changed = set_new_size (portalclusters);
cluster = &clusters[completed->cluster]; cluster = &clusters[completed->cluster];
for (i = 0; i < cluster->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
@ -338,7 +341,9 @@ LeafThread (void *_thread)
{ {
portal_t *portal; portal_t *portal;
int thread = (int) (intptr_t) _thread; int thread = (int) (intptr_t) _thread;
threaddata_t data;
memset (&data, 0, sizeof (data));
do { do {
portal = GetNextPortal (); portal = GetNextPortal ();
if (!portal) if (!portal)
@ -346,9 +351,10 @@ LeafThread (void *_thread)
if (working) if (working)
working[thread] = (int) (portal - portals); working[thread] = (int) (portal - portals);
PortalFlow (portal);
PortalCompleted (portal); PortalFlow (&data, portal);
PortalCompleted (&data, portal);
if (options.verbosity > 1) if (options.verbosity > 1)
printf ("portal:%5i mightsee:%5i cansee:%5i %5d/%d\n", printf ("portal:%5i mightsee:%5i cansee:%5i %5d/%d\n",
@ -555,8 +561,8 @@ CalcPortalVis (void)
if (options.verbosity > 0) { if (options.verbosity > 0) {
printf ("portalcheck: %i portaltest: %i portalpass: %i\n", printf ("portalcheck: %i portaltest: %i portalpass: %i\n",
c_portalcheck, c_portaltest, c_portalpass); stats.portalcheck, stats.portaltest, stats.portalpass);
printf ("c_vistest: %i c_mighttest: %i c_mightseeupdate: %i\n", c_vistest, c_mighttest, c_mightseeupdate); printf ("vistest: %i mighttest: %i mightseeupdate: %i\n", stats.vistest, stats.mighttest, stats.mightseeupdate);
} }
} }
@ -968,7 +974,7 @@ main (int argc, char **argv)
CalcVis (); CalcVis ();
if (options.verbosity >= 0) if (options.verbosity >= 0)
printf ("c_chains: %i%s\n", c_chains, printf ("chains: %i%s\n", stats.chains,
options.threads > 1 ? " (not reliable)" :""); options.threads > 1 ? " (not reliable)" :"");
BSP_AddVisibility (bsp, (byte *) visdata->str, visdata->size); BSP_AddVisibility (bsp, (byte *) visdata->str, visdata->size);