denoted in Cilk Plus. These loops look like void loop(int *a, int n) { #pragma cilk grainsize = 100 // optional cilk_for (int i = 0; i < n; i++) { a[i] = f(a[i]); } } This implements the parallel map idiom: the body of the loop, here a call to followed by an assignment to the array , is executed for each value of from zero to in an indeterminate order. The optional "grain size" pragma determines the coarsening: any sub-array of one hundred or fewer elements is processed sequentially. Although the Cilk specification does not specify the exact behavior of the construct, the typical implementation is a divide-and-conquer recursion, as if the programmer had written static void recursion(int *a, int start, int end) { if (end - start <= 100) { // The 100 here is the grainsize. for (int i = start; i < end; i++) { a[i] = f(a[i]); } } else { int midpoint = start + (end - start) / 2; cilk_spawn recursion(a, start, midpoint); recursion(a, midpoint, end); cilk_sync; } } void loop(int *a, int n) { recursion(a, 0, n); } The reasons for generating a divide-and-conquer program rather than the obvious alternative, a loop that spawn-calls the loop body as a function, lie in both the grainsize handling and in efficiency: doing all the spawning in a single task makes load balancing a bottleneck. A review of various parallel loop constructs on HPCwire found the construct to be quite general, but noted that the Cilk Plus specification did not stipulate that its iterations need to be data-independent, so a compiler cannot automatically vectorize a loop. The review also noted the fact that reductions (e.g., sums over arrays) need additional code. Reducers and hyperobjects Cilk++ added a kind of objects called hyperobjects, that allow multiple strands to share state without race conditions and without using explicit locks. Each strand has a view on the hyperobject that it can use and update; when the strands synchronize, the views are combined in a way specified by the programmer. The most common type of hyperobject is a reducer, which corresponds to the reduction clause in OpenMP or to the algebraic notion of a monoid. Each reducer has an identity element and an associative operation that combines two values. The archetypal reducer is summation of numbers: the identity element is zero, and the associative reduce operation computes a