Login  Register

Re: Multithreading and LazyObject

Posted by Luigi Ballabio on Jun 05, 2014; 1:46pm
URL: http://quantlib.414.s1.nabble.com/Multithreading-and-LazyObject-tp15310p15389.html

Hi Peter,
     good question.  I don't think there's a way to make other
calculations wait for the first, because the whole point of setting
calculated_ to true to begin with was exactly to make the calculation
look like it was completed even though it isn't... I don't think we
can avoid workarounds like yours.

Luigi


On Sun, May 25, 2014 at 8:34 PM, Peter Caspers <[hidden email]> wrote:

> Hi,
>
> I am currently trying to parallelize some computations in some pricing
> engines (using the OpenMP API). There is a complication due to calls
> to a lazy object model_ within a loop like this
>
> #pragma omp parallel for default(shared) firstprivate(p) if(expiry0>settlement)
>             for (Size k = 0; k < (expiry0 > settlement ? npv0.size() : 1);
>                  k++) {
> [...]
>                             model_->zerobond(arguments_.fixedPayDates[l],
>                                              expiry0, z[k], discountCurve_);
>
> The problem is that the first call triggers performCalculations() in
> model_ and before it has finished a call from another thread might
> occur, in which model_ is considered to be computed already, because
> in LazyObject the calculated_ flag is set to true right before the
> actual computation has started
>
>     inline void LazyObject::calculate() const {
>         if (!calculated_ && !frozen_) {
>             calculated_ = true;   // prevent infinite recursion in
>                                           // case of bootstrapping
>             try {
>                 performCalculations();
>             } catch (...) {
>                 calculated_ = false;
>                 throw;
>             }
>         }
>     }
>
> Of course it would not be desirable to trigger performCalculations()
> from two threads either. We'd rather need a mechanism which makes all
> threads wait until the first thread which triggered
> performCalculations() has finished (I guess). Also the check of the
> calculated_ flag and assignments to this variable would have to be
> made thread safe.
>
> I worked around this problem just by ensuring that model_ is
> calculated before the parallelized loop by a dummy call (at low
> additional cost)
>
> #ifdef _OPENMP
>             if(expiry0>settlement)
>                 model_->numeraire(QL_EPSILON);
> #endif
>
> I wonder however if someone has a more general and neater solution for this ?
>
> I am not interested in general multithreading ability at the moment,
> but more in this kind of "local" parallelizations, which seem quite
> attractive (the bermudan swaption engine above is already faster by a
> factor of 5 (on 8 cores), which is ok imo given the small effort to
> adapt the code).
>
> Thanks
> Peter
>
> ------------------------------------------------------------------------------
> "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
> Instantly run your Selenium tests across 300+ browser/OS combos.
> Get unparalleled scalability from the best Selenium testing platform available
> Simple to use. Nothing to install. Get started now for free."
> http://p.sf.net/sfu/SauceLabs
> _______________________________________________
> QuantLib-dev mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-dev



--
<https://implementingquantlib.blogspot.com>
<https://twitter.com/lballabio>

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev