Skip to content
All library documents

Parallel Monte Carlo Pricing with Independent Random Sequences

Article Quant Q&A · Author: saintb

Summary

The document considers splitting a Monte Carlo pricing workload across threads, running smaller simulations in parallel, and averaging their net present values. The accepted response says this can work, while recommending that threads avoid sharing objects to reduce thread-safety risks. Simply assigning different seeds does not guarantee that pseudorandom sequences will not overlap, which can undermine the intended sample size and estimates.

For low-discrepancy sampling, the response suggests using Sobol generators with skip-ahead support so each thread receives a distinct segment of the overall sequence. It also notes that dynamically created Mersenne Twister generators can address sequence overlap, with a QuantLib-oriented wrapper and precomputed instances mentioned for parallel use. These are implementation approaches, not reported benchmark results; generator setup and thread safety still matter to a reliable parallel calculation.

Key ideas

  • A Monte Carlo workload can be divided among threads and the resulting estimates averaged.
  • Avoid sharing objects across pricing threads to reduce concurrency hazards.
  • Different seeds alone do not guarantee non-overlapping pseudorandom sequences.
  • Sobol skip-ahead can assign separate sequence segments to parallel generators.
  • Dynamically created Mersenne Twister generators are another approach to separating streams.

Tags

Full text
# Multithreading Monte-Carlo pricing in QuantLib for a single product


# Multithreading Monte-Carlo pricing in QuantLib for a single product












I've been actively using QuantLib for structured product pricing using Monte Carlo. Due to the fact that at a great deal of paths are often needed and one needs to speed up the calculation and all that, I find myself having to think about ways to multithread the pricing. By profiling the code I obviously noted that the biggest bottleneck is not the product construction but running the Monte Carlo simulation.

Therefore let's suppose that if I needed 300k paths to somewhat accurately price the product, can I just spawn 10 threads, build the product in each one of them and make each thread calculate the NPV of the product with 30k paths all whilst using different seeds and then average the 10 different NPVs together?

## Answer by Luigi Ballabio (score 8, accepted)

https://quant.stackexchange.com/a/37499

Yes, it can work. However, keep in mind that:

- you'll be safer if you don't share any objects between threads; see my answer here, in particular the last point;

- even if you use different seeds, there's no guarantee that the generated sequences won't overlap. If you're willing to change the engine code so that you can pass the relevant parameters, a safer option would be to use a low-discrepancy generator such as Sobol, which has the ability to skip ahead in the sequence. This way, you could tell each generator to start at the correct place in the sequence of $2^N-1$ samples you'll use.

## Answer by Peter Caspers (score 6)

https://quant.stackexchange.com/a/37501

Adding to Luigi's answer, second point: The issue of overlapping Mersenne Twister sequences can be addressed with dynamically created Mersenne Twister Generators, cf. http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/DC/dc.html. I created a wrapper for the dcmt library so that it fits more easily into the QuantLib library, see https://github.com/pcaspers/QuantLib/blob/mtmc/ql/experimental/math/dynamiccreator.hpp. There are precomputed instances for parallel use in 8 threads.

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.