Deletions are marked like this. | Additions are marked like this. |
Line 22: | Line 22: |
loop | _: loop |
Line 24: | Line 24: |
for all fno normal[fno] = f (inputs) | _:_: for all fno normal[fno] = f (inputs) |
Line 26: | Line 26: |
for a few fno use normal[fno] | _:_: for a few fno use normal[fno] |
Line 28: | Line 28: |
change some inputs | _:_: change some inputs |
Line 30: | Line 30: |
end loop | _: end loop |
Line 32: | Line 32: |
change some inputs | _: change some inputs |
Line 34: | Line 34: |
use some normal[fno] | _: use some normal[fno] |
Line 40: | Line 40: |
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] |
. 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
_: 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
for a few fno if normal[fno].deferred normal[fno] = f (inputs); normal[fno].deferred = false change some inputs use some normal[fno]