--- layout: default title: Enabling parallelization groups: - {name: Home, url: ''} - {name: Tutorials , url: 'tutorials/'} --- - [Parallel updating](#parallel-updating) - [Concurrent input](#concurrent-input) - [Selecting a propagation engine](#selecting-a-propagation-engine) ## Parallel updating Enabling parallel propagation of changes - or parallel updating as we refer to it from now on - turns out to be straightforward; all we have to do is selecting the `parallel` policy in the domain definition: {% highlight C++ %} #include "react/Domain.h" #include "react/Signal.h" #include "react/Event.h" REACTIVE_DOMAIN(D, parallel) USING_REACTIVE_DOMAIN(D) int calcX(int); int calcY(int); int calcZ(int); VarSignalT Input = MakeVar(0); SignalT X = MakeSignal(Input, calcX); SignalT Y = MakeSignal(Input, calcY); SignalT Z = MakeSignal(With(X, Y), calcZ); {% endhighlight %} Assuming `calcX` and `calcY` are computationally expensive, they could be re-calculated in parallel after `Input` has been changed. How exactly this is handled internally is up to the propagation engine; it's explained in detail [here]. In summary, the propagation engine will - use TBB tasks to parallelize upates, which in turn are mapped to a thread pool; - try to identify expensive computations at runtime to determine when parallelization is worthwhile; - agglomerate computations dynamically to reduce overhead. ## Concurrent input Parallel updating is _internal_ concurrency, as it may execute multiple updates of the same turn concurrently. But what we really want there is parallelism - that is, running them on multiple CPUs in parallel. On the other hand, there's _external_ concurrency, which is refers to the ability of handling concurrent input. This is similar to how a concurrent queue supports push and pop operations from multiple threads at the same time. To enable concurrent input, we use a concurrency policy with the `_concurrent` suffix: {% highlight C++ %} REACTIVE_DOMAIN(D1, sequential_concurrent) REACTIVE_DOMAIN(D2, parallel_concurrent) D1::EventSourceT Source1 = MakeEventSource(); D2::EventSourceT Source2 = MakeEventSource(); {% endhighlight %} {% highlight C++ %} auto f = [&] { for (int i=0; i