A holder is a hyperobject that isolates parallel uses of a common variable in cases where it is not necessary to preserve changes from different parallel strands. Each parallel strand will see and manipulate a different view of the holder, just as in the case of a reducer.
A holder is similar to thread-local storage but is specifically designed to work with the fork-join structure of Intel® Cilk™ Plus.
A holder has the following characteristics:
The view of a holder before the first spawn within a function is the same as the view after each sync (as in the case of a reducer).
The view of a holder within the first spawned child of a function (or the first child spawned after a sync) is the same as the view on entry to the function.
The view of a holder before entering a cilk_for loop is the same as the view during the first iteration of the loop and the view at the end of the loop.
The value stored in the view of a holder in the continuation of a spawn or at the beginning of an arbitrary iteration of a cilk_for loop is non-deterministic. It is generally recommended that the holder be explicitly placed into a known state in these situations.
A holder can be used as an alternative to parameter passing because it can replace non-local variables without massive refactoring. A holder takes advantage of the fact that, most of the time, a holder view does not change after a spawn or from one iteration of a parallel for loop to the next (stealing is the exception). When the holder view is a large object that is expensive to construct, this optimization can save significant time by avoiding the creation of a separate local object for each view.
In addition, a holder using the "keep last" policy has the same value after a sync as the serialization of the same program. This characteristic often allows the program to avoid recomputing a value.