Differences between revisions 1 and 6 (spanning 5 versions)
Revision 1 as of 2018-03-13 00:18:42
Size: 872
Editor: BevinBrett
Comment:
Revision 6 as of 2018-03-13 00:53:42
Size: 1691
Editor: BevinBrett
Comment:
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, which does unnecessary calculations of the face normals ====
mrisComputeOptimalRetessellation and mrisComputeRandomRetessellation have a similar structure
Line 6: Line 7:
mris_fix_topology has a hot loop _:_: it loops over a set of patches, or iterates on one patch. For each patch it calls
Line 8: Line 9:
 ___: mrisComputeOptimalRetessellation and mrisComputeRandomRetessellation have a similar structure _:_:_: mrisDefectPatchFitness, which calls
Line 10: Line 11:
___: ___: a computeDefectContext is constructed here _:_:_:_: mrisComputeDefectLogLikelihood, which calls
Line 12: Line 13:
___:___: then it loops over a set of patches, or iterates on one patch. For each patch it calls _:_:_:_:_: mrisComputeDefectMRILogUnlikelihood, which
Line 14: Line 15:
___:___:___: mrisDefectPatchFitness, which calls _:_:_:_:_:_: does an expensive computation all the face normals for ALL the faces
Line 16: Line 17:
___:___:___: ___: mrisComputeDefectLogLikelihood, which calls _:_:_:_:_:_: does two other expensive steps, which only use a few of the face normals
Line 18: Line 19:
___:___:___: ___: ___: mrisComputeDefectMRILogUnlikelihood, which ==== To simplify, the original code does this ====
_: loop
Line 20: Line 22:
___:___:___: ___: ___:___: does an expensive computation all the face normals for ALL the faces _:_: for all fno normal[fno] = f (inputs)
Line 22: Line 24:
___:___:___: ___: ___:___: does two other expensive steps, which only use a few of the face normals _:_: for a few fno use normal[fno]

_: 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: use normal[fno], computing it from f (inputs) if is deferred, and changing it to being no-longer deferred

_: end loop

_: compute any remaining deferred normal[fno] before their inputs can change

_: change some inputs

_: use some normal[fno]

==== How can we test it gets the right answers? ====
When checking code is enabled, the normal[fno] is computed from the inputs twice - once when it is deferred, and again when it is undeferred. It is checked that these two values are the same.

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

_:_: 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]

_: 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: use normal[fno], computing it from f (inputs) if is deferred, and changing it to being no-longer deferred

_: end loop

_: compute any remaining deferred normal[fno] before their inputs can change

_: change some inputs

_: use some normal[fno]

How can we test it gets the right answers?

When checking code is enabled, the normal[fno] is computed from the inputs twice - once when it is deferred, and again when it is undeferred. It is checked that these two values are the same.

MorphoOptimizationProject_BetterSerialCode_DeferCalculations (last edited 2021-09-22 09:46:34 by DevaniCordero)