|
98 | 98 | <div class="textblock"><p>Running a for-loop in parallel is the most fundamental building block in parallel programming. In this chapter, we are going to demonstrate how to use Cpp-Taskflow to create a task dependency graph of parallel for-loop.</p> |
99 | 99 | <h1><a class="anchor" id="RangeBasedForLoop"></a> |
100 | 100 | Range-based For-loop</h1> |
101 | | -<p>Cpp-Taskflow has a STL-style method <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="constructs a task dependency graph of range-based parallel_for ">tf::Taskflow::parallel_for(I beg, I end, C&& callable, size_t chunk)</a> that takes a range of items and applies a callable to each of the item in parallel. The method constructs a task dependency graph representing this workload and returns a task pair as two synchronization points to this task graph.</p> |
| 101 | +<p>Cpp-Taskflow has a STL-style method <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="creates a task from a given callable object without access to the result ">tf::Taskflow::parallel_for(I beg, I end, C&& callable, size_t chunk)</a> that takes a range of items and applies a callable to each of the item in parallel. The method constructs a task dependency graph representing this workload and returns a task pair as two synchronization points to this task graph.</p> |
102 | 102 | <div class="fragment"><div class="line"> 1: <a class="code" href="classtf_1_1BasicTaskflow.html">tf::Taskflow</a> taskflow;</div><div class="line"> 2:</div><div class="line"> 3: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector<int></a> items {1, 2, 3, 4, 5, 6, 7, 8};</div><div class="line"> 4:</div><div class="line"> 5: <span class="keyword">auto</span> [S, T] = taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(items.begin(), items.end(), [] (<span class="keywordtype">int</span> item) {</div><div class="line"> 6: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/thread/get_id.html">std::this_thread::get_id</a>() << <span class="stringliteral">" runs "</span> << item << <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/manip/endl.html">std::endl</a>;</div><div class="line"> 7: });</div><div class="line"> 8:</div><div class="line"> 9: S.work([] () { <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <span class="stringliteral">"S\n"</span>; }).name(<span class="stringliteral">"S"</span>);</div><div class="line">10: T.work([] () { <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <span class="stringliteral">"T\n"</span>; }).name(<span class="stringliteral">"T"</span>);</div><div class="line">11:</div><div class="line">12: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#adac448e1cc44307856b3116d7ed5490f">dump</a>();</div><div class="line">13:</div><div class="line">14: taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>();</div></div><!-- fragment --><p>The above code generates the following task dependency graph. The label 0x56* represents an internal task node to execute the callable object. By default (<code>chunk=0</code>), Cpp-Taskflow evenly partitions and distributes the workload to all threads. In our example of eight tasks and four workers, each internal node is responsible for two items.</p> |
103 | 103 | <div class="image"> |
104 | 104 | <img src="parallel_for1.png" alt="parallel_for1.png" width="60%"/> |
@@ -131,7 +131,7 @@ <h1><a class="anchor" id="ConstructTheGraphExplicitly"></a> |
131 | 131 | <div class="fragment"><div class="line">1: taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(0, 10, 2, [] (<span class="keywordtype">int</span> i) {</div><div class="line">2: <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << <span class="stringliteral">"parallel on "</span> << i << <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/manip/endl.html">std::endl</a>;</div><div class="line">3: }, 2);</div><div class="line">4: <span class="comment">// print 0, 2, 4, 6, 8 (three groups {0, 2}, {4, 6}, {8})</span></div></div><!-- fragment --><p>By default, Cpp-Taskflow performs even partition across the number of available threads if no group size is given.</p> |
132 | 132 | <h1><a class="anchor" id="Chapter3Example1"></a> |
133 | 133 | Example 1: Parallel Map</h1> |
134 | | -<p>This example demonstrates how to use <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="constructs a task dependency graph of range-based parallel_for ">tf::Taskflow::parallel_for</a> to create a parallel map pattern. The map operator modifies each item in the container to one if it is an odd number, or zero if it is an even number.</p> |
| 134 | +<p>This example demonstrates how to use <a class="el" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e" title="creates a task from a given callable object without access to the result ">tf::Taskflow::parallel_for</a> to create a parallel map pattern. The map operator modifies each item in the container to one if it is an odd number, or zero if it is an even number.</p> |
135 | 135 | <div class="fragment"><div class="line"><span class="preprocessor">#include <taskflow/taskflow.hpp></span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line"></div><div class="line"> <a class="code" href="classtf_1_1BasicTaskflow.html">tf::Taskflow</a> taskflow;</div><div class="line"></div><div class="line"> <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector<int></a> items{1, 2, 3, 4, 5, 6, 7, 8};</div><div class="line"></div><div class="line"> taskflow.<a class="code" href="classtf_1_1FlowBuilder.html#a84d411f16939bc158c5a90256e5d210e">parallel_for</a>(items.begin(), items.end(), [] (<span class="keywordtype">int</span>& item) {</div><div class="line"> item = (item & 1) ? 1 : 0;</div><div class="line"> });</div><div class="line"></div><div class="line"> taskflow.<a class="code" href="classtf_1_1BasicTaskflow.html#a37ef86998f23ee7315be032c40fe815e">wait_for_all</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">for</span>(<span class="keyword">auto</span> item : items) {</div><div class="line"> <a class="codeRef" doxygen="/home/twhuang/PhD/Code/cpp-taskflow/docs/cppreference-doxygen-web.tag.xml:http://en.cppreference.com/w/" href="http://en.cppreference.com/w/cpp/io/basic_ostream.html">std::cout</a> << item << <span class="stringliteral">" "</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>The program outputs the following:</p> |
136 | 136 | <div class="fragment"><div class="line">1 0 1 0 1 0 1 0 </div></div><!-- fragment --><h1><a class="anchor" id="Chapter3Example2"></a> |
137 | 137 | Example 2: Pipeline a Parallel For-loop</h1> |
|
0 commit comments