@@ -142,9 +142,9 @@ attribution: true
142
142
143
143
A new form of Statement is introduced:
144
144
145
- _ Cilk_scope { Statement* }
145
+ cilk_scope { Statement* }
146
146
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.
148
148
149
149
## Semantics
150
150
@@ -682,9 +682,9 @@ else ((<var>first</var>) <code>-</code> (<var>limit</var>)) <code>/</code> <code
682
682
a++;</pre >
683
683
<p>The call to function <code>f</code> is the spawn point and the statement <code>a++;</code>
684
684
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>
686
686
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>
688
688
a + b</code> take place in the child.</p>
689
689
<p>If a statement is followed by an implicit sync, that sync is the spawn continuation.</p>
690
690
<p class="note">Programmer note: The sequencing may be more clear if</p>
@@ -732,115 +732,6 @@ a++;</pre>
732
732
the serial execution order of the program) are destructed in an unspecified order
733
733
before the earliest exception is caught.</p>
734
734
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
-
844
735
# Disclaimer and other legal information
845
736
846
737
<p >Copyright (c) 2020 Massachusetts Institute of Technology</p >
0 commit comments