@@ -142,9 +142,9 @@ attribution: true
142142
143143A new form of Statement is introduced:
144144
145- _ Cilk_scope { Statement* }
145+ cilk_scope { Statement* }
146146
147- Statements within _ Cilk_scope are executed as usual. There is an implicit _ Cilk_sync at the end of the statements included within the _ Cilk_scope construct.
147+ Statements within cilk_scope are executed as usual. There is an implicit cilk_sync at the end of the statements included within the cilk_scope construct.
148148
149149## Semantics
150150
@@ -682,9 +682,9 @@ else ((<var>first</var>) <code>-</code> (<var>limit</var>)) <code>/</code> <code
682682a++;</pre >
683683 <p>The call to function <code>f</code> is the spawn point and the statement <code>a++;</code>
684684 is the continuation. The expression <code>a + b</code> and the initialization of
685- the temporary variable holding that value, and the evaluation of <code>x\\\\\\[g()]</code>
685+ the temporary variable holding that value, and the evaluation of <code>x\\\\\\\ [g()]</code>
686686 take place before the spawn point. The execution of <code>f</code>, the assignment
687- to <code>x\\\\\\[g()]</code>, and the destruction of the temporary variable holding <code>
687+ to <code>x\\\\\\\ [g()]</code>, and the destruction of the temporary variable holding <code>
688688 a + b</code> take place in the child.</p>
689689 <p>If a statement is followed by an implicit sync, that sync is the spawn continuation.</p>
690690 <p class="note">Programmer note: The sequencing may be more clear if</p>
@@ -732,115 +732,6 @@ a++;</pre>
732732 the serial execution order of the program) are destructed in an unspecified order
733733 before the earliest exception is caught.</p>
734734
735- # Hyperobjects
736-
737- ## Description
738-
739- <p >Cilk <ins >Plus</ins > defines a category of objects called “ ; hyperobjects” ; .
740- Hyperobjects allow thread-safe access to shared objects by giving each <del>parallel</del>
741- strand <ins>running in parallel</ins> a separate instance of the object.</p>
742- <p >Parallel code uses a hyperobject by performing a <dfn >hyperobject lookup</dfn > operation.
743- The hyperobject lookup returns a reference to an object, called a <dfn>view,</dfn>
744- that is guaranteed not to be shared with any other active strands in the program.
745- The sequencing of a hyperobject lookup within an expression is not specified. The
746- runtime system creates a view when needed, using callback functions provided by
747- the hyperobject type. When strands synchronize, the hyperobject views are merged
748- into a single view, using another callback function provided by the hyperobject
749- type.</p>
750- <p >The view of a hyperobject visible to a program may change at any spawn or sync (including
751- the implicit spawns and syncs within a <code>cilk_for</code> loop). The identity
752- (address) of the view does not change within a single strand. The view of a given
753- hyperobject visible within a given strand is said to be <dfn>associated</dfn> with
754- that view. A hyperobject has the same view before the first spawn within a task
755- block as after a sync within the same task block, even though the thread ID may
756- not be the same (i.e., hyperobject views are not tied to threads). A hyperobject
757- has the same view upon entering and leaving a <code>cilk_for</code> loop and within
758- the first iteration (at least) of the <code>cilk_for</code> loop. A special view
759- is associated with a hyperobject when the hyperobject is initially created. This
760- special view is called the <dfn>leftmost view</dfn> or <dfn>earliest view</dfn>
761- because it is always visible to the leftmost (earliest) descendent in the depth-first,
762- left-to-right traversal of the program's spawn tree. The leftmost view is given
763- an initial value when the hyperobject is created.</p>
764- <p class =" note " >Programmer note: If two expressions compute the same address for a view,
765- then they have not been scheduled in parallel. This property yields one of the simplest
766- ways by which a program can observe the runtime behavior of the scheduler.</p>
767- <p class =" note " >Implementation note: An implementation can optimize hyperobject lookups
768- by performing them only when a view has (or might have) changed. This optimization
769- can be facilitated by attaching implementation-specific attributes to the hyperobject
770- creation, lookup, and/or destruction operations.</p>
771-
772- ## Reducers
773-
774- <p >The vast majority of hyperobjects belong to a category known as “ ; reducers.” ;
775- Each reducer type provides a <code>reduce</code> callback operation that merges
776- two views in a manner specific to the reducer. For a pair of views <var>V<sub>1</sub></var>
777- and <var>V<sub>2</sub></var>, the result of calling <code>reduce(</code><var>V<sub>1</sub></var><code>,</code>
778- <var>V<sub>2</sub></var><code>)</code> is notated as <var>V<sub>1</sub>⊗V<sub>2</sub></var>.
779- Each reducer also provides an <code>identity</code> callback operation that initializes
780- a new view.</p>
781- <p >The <code >reduce</code > callback for a “ ; classical” ; reducer implements
782- an operation ⊗ such that (<var>a⊗b</var>)⊗<var>c==a</var>⊗(<var>b⊗c</var>)
783- (i.e., ⊗ is associative). The view-initialization callback for such a reducer
784- sets the view to an identity value <var>I</var> such that <var>I⊗v==v</var>
785- and <var>v⊗I==v</var> for any value <var>v</var> of <var>value_type</var>.
786- Given an associative ⊗ and an identity <var>I</var>, the triplet (<var>value_type</var>,
787- ⊗, <var>I</var>) describes a mathematical <dfn>monoid</dfn>. For example,
788- (<code>int</code>, <code>+</code>, <code>0</code>) is a monoid, as is (<code>list</code>,
789- <code>concatenate</code>, <var>empty</var>). If each individual view, <var>R</var>,
790- of a classical reducer is modified using only expressions that are equivalent to
791- <var>R</var>←<var>R</var>⊗<var>v</var> (where <var>v</var> is of <var>
792- value_type</var>), then the reducer computes the same value in the parallel
793- program as would be computed in the serialization of the program. (In actuality,
794- the “⊗” in the expression “<var>R</var>←<var>R</var>⊗<var>v</var>”
795- can represent a set of mutually-associative operations. For example, <code>+=</code>
796- and <code>-=</code> are mutually associative.) For example, a spawned function or
797- <code>cilk_for</code> body can append items onto the view of a list reducer with
798- monoid (<code>list</code>, <code>concatenate</code>, <var>empty</var>). At the end
799- of the parallel section of code, the reducer's view contains the same list items
800- in the same order as would be generated in a serial execution of the same code.</p>
801- <p >Given a set of strands entering a sync, <var >S<sub >1</sub >,S<sub >2</sub >,S<sub >3</sub >,… ; S<sub >n</sub ></var >,
802- associated with views <var>V<sub>1</sub>,V<sub>2</sub>,V<sub>3</sub>,…V<sub>n</sub></var>,
803- respectively such that <var>S<sub>i</sub></var> is earlier in the serial ordering
804- than <var>S<sub>i+1</sub></var>, a single view, <var>W</var>, emerges from the sync
805- with value <var>W←V<sub>1</sub>⊗V<sub>2</sub>⊗V<sub>3</sub>⊗…⊗V<sub>n</sub></var>,
806- such that the left-to-right order is maintained but the grouping (associativity)
807- of the operations is unspecified. The timing of this “reduction” is
808- unspecified – in particular, subsequences typically will be computed asynchronously
809- as child tasks complete. Every view except the one emerging from the sync is destroyed
810- after the merge. If any of the strands does not have an associated view, then the
811- invocation of the <code>reduce</code> callback function can be elided (i.e., the
812- missing view is treated as an identity).</p>
813- <p >A strand is never associated with more than one view for a given reducer, but multiple
814- strands can be associated with the same view if those strands are not scheduled
815- in parallel (at run time). Specifically, for a given reducer, the association of
816- a strand to a view of the reducer obeys the following rules:</p>
817- <ol >
818- <li>The strand that initializes the reducer is associated with the leftmost view.</li>
819- <li>If two strands execute in series (i.e., both strands are part of a larger strand),
820- then both are associated with the same view.</li>
821- <li>The child strand of a spawn is associated with the same view as the strand that
822- entered the spawn.</li>
823- <li>If the continuation strand of a spawn is scheduled in parallel with the child, then
824- the continuation strand is associated with a new view, initialized using <code>identity</code>.
825- The implementation may create the new view at any time up until the first hyperobject
826- lookup following the spawn. If the continuation strand does not perform a hyperobject
827- lookup, then the implementation is not required to create a view for that strand.</li>
828- <li>If the continuation strand of a spawn is not scheduled in parallel with the child
829- strand (i.e., the child and the continuation execute in series), then the continuation
830- strand is associated with the same view as the child strand.</li>
831- <li>The strand that emerges from a sync is associated with the same view as the leftmost
832- strand entering the sync.</li>
833- </ol >
834- <p >Even before the final reduction, the leftmost view of a reducer will contain the
835- same value as in the serial execution. Other views, however, will contain partial
836- values that are different from the serial execution.</p>
837- <p >If ⊗ ; is not associative or if <code >identity</code > does not yield a true
838- identity value then the result of a set of reductions will be non-deterministic
839- (i.e., it will vary based on runtime scheduling). Such “non-classical”
840- reducers are nevertheless occasionally useful. Note that, for a classical reducer,
841- the ⊗ operator needs to be associative, but does not need to be commutative.</p>
842-
843-
844735# Disclaimer and other legal information
845736
846737<p >Copyright (c) 2020 Massachusetts Institute of Technology</p >
0 commit comments