Request for Changes-52: Faster BandMathX

From OTBWiki
Jump to: navigation, search

[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.