Deletions are marked like this. | Additions are marked like this. |
Line 4: | Line 4: |
Each face had a normal vector and area stored in the nx,ny,nz,orig_area members of the FACE struct. mris_fix_topology has a hot loop |
mris_fix_topology has a hot loop, which does unnecessary calculations of the face normals |
Line 9: | Line 7: |
_: _: a computeDefectContext is constructed here |
|
Line 16: | Line 12: |
_:_:_: _: mrisComputeDefectLogLikelihood, which calls | _:_:_:_: mrisComputeDefectLogLikelihood, which calls |
Line 18: | Line 14: |
_:_:_: _: _: mrisComputeDefectMRILogUnlikelihood, which | _:_:_:_:_: mrisComputeDefectMRILogUnlikelihood, which |
Line 20: | Line 16: |
_:_:_: _: _:_: does an expensive computation all the face normals for ALL the faces | _:_:_:_:_:_: does an expensive computation all the face normals for ALL the faces |
Line 22: | Line 18: |
_:_:_: _: _:_: does two other expensive steps, which only use a few of the face normals |
_:_:_:_:_:_: does two other expensive steps, which only use a few of the face normals To simplify, the original code does this loop for all fno normal[fno] = f (inputs) for a few fno use normal[fno] change some inputs end loop change some inputs use some normal[fno] Since only a few of the face normals are used, it is a waste of time to calculate all of them every time around the loop! This is replaced by code that does loop for all fno __normal[fno].deferred = true__ for a few fno __if normal[fno].deferred normal[fno] = f (inputs); normal[fno].deferred = false__ change some inputs end loop __for a few fno if normal[fno].deferred normal[fno] = f (inputs); normal[fno].deferred = false__ change some inputs use some normal[fno] |
A variety of techniques have been used.
Deferring calculations until needed
mris_fix_topology has a hot loop, which does unnecessary calculations of the face normals
mrisComputeOptimalRetessellation and mrisComputeRandomRetessellation have a similar structure
_:_: then it loops over a set of patches, or iterates on one patch. For each patch it calls
_:_:_: mrisDefectPatchFitness, which calls
_:_:_:_: mrisComputeDefectLogLikelihood, which calls
_:_:_:_:_: mrisComputeDefectMRILogUnlikelihood, which
_:_:_:_:_:_: does an expensive computation all the face normals for ALL the faces
_:_:_:_:_:_: does two other expensive steps, which only use a few of the face normals
To simplify, the original code does this
- loop
- for all fno normal[fno] = f (inputs) for a few fno use normal[fno] change some inputs
Since only a few of the face normals are used, it is a waste of time to calculate all of them every time around the loop!
This is replaced by code that does
- loop
for all fno normal[fno].deferred = true
for a few fno if normal[fno].deferred normal[fno] = f (inputs); normal[fno].deferred = false change some inputs
for a few fno if normal[fno].deferred normal[fno] = f (inputs); normal[fno].deferred = false change some inputs use some normal[fno]