|
Size: 872
Comment:
|
Size: 1691
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.
