Request for Changes-52: Faster BandMathX
Contents
[Request for Changes - 52] Faster BandMathX
Status
- Author: Guillaume Pasero
- Additional Contributors (if different than authors)
- Submitted on 09.08.2016
- Proposed target release : 5.8
- Adopted : +3 from Julien, Rémi and Guillaume
- Merged : 31a875eb77fca8747b19f32783665dd20f1d4266
Summary
The purpose of this RFC is to speed up the BandMathX filter, which has a tendency to become too slow on large images.
Rationale
See Request for Comments 34.
Among the 4 items to seek better performance :
- Item 1 (only 1 call to SetExpr() ) has been implemented.
- Item 2 (wrap iterators inside mup::Value) is not as promising as it seemed. The values returned by iterators should be cast anyway into the types supported by muparserX. And if a variable is used several times in the expressions, wrapping the iterator inside a mup::Value will cause several calls to Iterator::Get() and several type conversions.
- Item 3 was already implemented (only the variables used in the expressions are handled during processing)
- Item 4 doesn't seem possible to implement. We still want to iterate over pixel positions, then iterate over expressions. The use of a mechanism to wrap the different behaviours depending on the returned type may not bring any performance improvement compared to the current switch/case.
Implementation details
Classes and files
M Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.h M Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.txx M Modules/Filtering/MathParserX/include/otbParserX.h M Modules/Filtering/MathParserX/src/otbParserX.cxx
The optimizations were done in otb::ParserX and otb::BandMathXImageFilter :
- otb::ParserX : new function EvalRef() that returns a reference to a mup::IValue instead of a copy.
- otb::BandMathXImageFilter :
- use one parser per thread and per expression to avoid the SetExpr() at each pixel position (item 1 in the RFComment)
- use values returned by references when possible
- fix the output iterators : use a temporary pixel value and a single outIt.Set(...).
- use scanline iterators
- use an iterator over variables
No API change was made to the application BandMathX.
I have run several test with the BandMathX application, the performance improvements ranges from x5 to x22 times faster. The lowest perfomance gain is observed with a single input image and the expression "im1".
Applications
No modification.
Tests
M Modules/Filtering/MathParserX/test/otbBandMathXImageFilter.cxx
The test has been fixed : potential issue with the manipulation of output iterators. As in otb::BandMathXImageFilter, the output value was set in the image using :
outIt.Get()[0] = outputValue;
This was miraculously working as the iterator is optimized and returns a proxy and not a copy.
Documentation
No update.
Additional notes
List remaining open issues if any, and additional notes.