Skip to content

Commit 4f4f24c

Browse files
tsung-wei-huangtwhuang
andauthored
optimized parallel algorithms (taskflow#427)
Co-authored-by: twhuang <[email protected]>
1 parent a757aa5 commit 4f4f24c

59 files changed

Lines changed: 2751 additions & 694 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

benchmarks/mandelbrot/omp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ void mandelbrot_omp(unsigned num_threads, int d = D) {
77

88
# pragma omp parallel shared (d) private (i, j)
99
{
10-
# pragma omp for schedule(dynamic, 1)
10+
# pragma omp for schedule(guided, 1)
1111
for(i=0; i<H ;i ++) {
1212
for(j=0; j<W; j++) {
1313

docs/PrioritizedTasking.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ <h3>Contents</h3>
5555
<li><a href="#AssignAPriorityToATask">Assign a Priority to a Task</a></li>
5656
</ul>
5757
</nav>
58-
<p>This chapter demonstrates how to assigns a task a priority to <em>hint</em> the scheduler about one task of a higher priority should start earlier than another task of a lower priority. Task priorities are useful in many cases. For instance, we may prioritize some tasks over others to improve responsiveness or data locality of parallel tasks.</p><section id="AssignAPriorityToATask"><h2><a href="#AssignAPriorityToATask">Assign a Priority to a Task</a></h2><p>Taskflow supports three different priority levels, <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fab89de3b4b81c4facfac906edf29aec8c" class="m-doc">tf::<wbr />TaskPriority::<wbr />HIGH</a>, <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fa1e23852820b9154316c7c06e2b7ba051" class="m-doc">tf::<wbr />TaskPriority::<wbr />NORMAL</a>, and <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fa41bc94cbd8eebea13ce0491b2ac11b88" class="m-doc">tf::<wbr />TaskPriority::<wbr />LOW</a>, as defined in <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346f" class="m-doc">tf::<wbr />TaskPriority</a>. When there are parallel tasks (i.e., no dependencies), Taskflow will <code>try</code> to execute tasks of higher priorities before tasks of lower priorities. By default, all tasks have the highest priorities (<code><a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fab89de3b4b81c4facfac906edf29aec8c" class="m-doc">TaskPriority::<wbr />HIGH</a></code>) unless otherwise assigned.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="nf">executor</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
58+
<p>This chapter demonstrates how to assigns a task a priority to <em>hint</em> the scheduler about one task of a higher priority should start earlier than another task of a lower priority. Task priorities are useful in many cases. For instance, we may prioritize some tasks over others to improve responsiveness or data locality of parallel tasks.</p><section id="AssignAPriorityToATask"><h2><a href="#AssignAPriorityToATask">Assign a Priority to a Task</a></h2><p>Taskflow supports three different priority levels, <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fab89de3b4b81c4facfac906edf29aec8c" class="m-doc">tf::<wbr />TaskPriority::<wbr />HIGH</a>, <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fa1e23852820b9154316c7c06e2b7ba051" class="m-doc">tf::<wbr />TaskPriority::<wbr />NORMAL</a>, and <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fa41bc94cbd8eebea13ce0491b2ac11b88" class="m-doc">tf::<wbr />TaskPriority::<wbr />LOW</a>, as defined in <a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346f" class="m-doc">tf::<wbr />TaskPriority</a>. When there are parallel tasks (i.e., no dependencies), Taskflow will <code>try</code> to execute tasks of higher priorities before tasks of lower priorities. By default, all tasks have the highest priorities (<code><a href="namespacetf.html#ac9f4add8f716ed323b0bdbbc1d89346fab89de3b4b81c4facfac906edf29aec8c" class="m-doc">tf::<wbr />TaskPriority::<wbr />HIGH</a></code>) unless otherwise assigned.</p><pre class="m-code"><span class="n">tf</span><span class="o">::</span><span class="n">Executor</span><span class="w"> </span><span class="nf">executor</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
5959
<span class="n">tf</span><span class="o">::</span><span class="n">Taskflow</span><span class="w"> </span><span class="n">taskflow</span><span class="p">;</span><span class="w"></span>
6060

6161
<span class="kt">int</span><span class="w"> </span><span class="n">counter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>

docs/annotated.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,15 @@ <h1>Classes</h1>
9494
<li>class <a href="classtf_1_1Taskflow.html" class="m-doc">Taskflow</a> <span class="m-doc">class to create a taskflow object</span></li>
9595
<li>class <a href="classtf_1_1TaskQueue.html" class="m-doc">TaskQueue</a> <span class="m-doc">Lock-free unbounded single-producer multiple-consumer queue.</span></li>
9696
<li>class <a href="classtf_1_1TaskView.html" class="m-doc">TaskView</a> <span class="m-doc">class to access task information from the observer interface</span></li>
97-
<li>class <a href="classtf_1_1TFProfObserver.html" class="m-doc">TFProfObserver</a> <span class="m-doc">class to create an observer based on the built-in taskflow profiler format</span></li>
97+
<li class="m-doc-collapsible collapsed">
98+
<a href="#" onclick="return toggle(this)">class</a> <a href="classtf_1_1TFProfObserver.html" class="m-doc">TFProfObserver</a> <span class="m-doc">class to create an observer based on the built-in taskflow profiler format</span>
99+
<ul class="m-doc">
100+
<li>struct <a href="structtf_1_1TFProfObserver_1_1TaskSummary.html" class="m-doc">TaskSummary</a> <span class="m-doc"></span></li>
101+
<li>struct <a href="structtf_1_1TFProfObserver_1_1WorkerSummary.html" class="m-doc">WorkerSummary</a> <span class="m-doc"></span></li>
102+
</ul>
103+
</li>
98104
<li>class <a href="classtf_1_1Worker.html" class="m-doc">Worker</a> <span class="m-doc">class to create a worker in an executor</span></li>
99-
<li>class <a href="classtf_1_1WorkerInterface.html" class="m-doc">WorkerInterface</a> <span class="m-doc">class <a href="classtf_1_1WorkerInterface.html" class="m-doc">WorkerInterface</a></span></li>
105+
<li>class <a href="classtf_1_1WorkerInterface.html" class="m-doc">WorkerInterface</a> <span class="m-doc">class to configure worker behavior in an executor</span></li>
100106
<li>class <a href="classtf_1_1WorkerView.html" class="m-doc">WorkerView</a> <span class="m-doc">class to create an immutable view of a worker in an executor</span></li>
101107
</ul>
102108
</li>

docs/classtf_1_1TFProfObserver.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ <h3>Contents</h3>
7575
<span class="n">executor</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">taskflow</span><span class="p">).</span><span class="n">wait</span><span class="p">();</span><span class="w"></span>
7676

7777
<span class="c1">// dump the thread activities to Taskflow Profiler format.</span>
78-
<span class="n">observer</span><span class="o">-&gt;</span><span class="n">dump</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">);</span><span class="w"></span></pre><p>We recommend using our <a href="https://taskflow.github.io/tfprof/">Taskflow Profiler</a> python script to observe thread activities instead of the raw function call. The script will turn on environment variables needed for observing all executors in a taskflow program and dump the result to a valid, clean JSON file compatible with the format of <a href="https://taskflow.github.io/tfprof/">Taskflow Profiler</a>.</p>
78+
<span class="n">observer</span><span class="o">-&gt;</span><span class="n">dump</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="p">);</span><span class="w"></span></pre>
7979
<section id="base-classes">
8080
<h2><a href="#base-classes">Base classes</a></h2>
8181
<dl class="m-doc">
@@ -96,6 +96,14 @@ <h2><a href="#pub-methods">Public functions</a></h2>
9696
<span class="m-doc-wrap-bumper">auto <a href="#a59e82cb3f9b0ada38aa1ddea14f14d02" class="m-doc-self">dump</a>(</span><span class="m-doc-wrap">) const -&gt; <a href="http://en.cppreference.com/w/cpp/string/basic_string.html" class="m-doc-external">std::<wbr />string</a></span>
9797
</dt>
9898
<dd>dumps the timelines into a JSON string</dd>
99+
<dt id="a6102cedbaf2e40f8b8ff916827297198">
100+
<span class="m-doc-wrap-bumper">void <a href="#a6102cedbaf2e40f8b8ff916827297198" class="m-doc-self">summary</a>(</span><span class="m-doc-wrap"><a href="http://en.cppreference.com/w/cpp/io/basic_ostream.html" class="m-doc-external">std::<wbr />ostream</a>&amp; ostream) const</span>
101+
</dt>
102+
<dd>shows the summary report through an output stream</dd>
103+
<dt id="a6f12a927a328bd594cf6c3c3a6bfe992">
104+
<span class="m-doc-wrap-bumper">auto <a href="#a6f12a927a328bd594cf6c3c3a6bfe992" class="m-doc-self">summary</a>(</span><span class="m-doc-wrap">) const -&gt; <a href="http://en.cppreference.com/w/cpp/string/basic_string.html" class="m-doc-external">std::<wbr />string</a></span>
105+
</dt>
106+
<dd>returns the summary report in a string</dd>
99107
<dt id="a5e1f63034a96a5a79cef6da412efd203">
100108
<span class="m-doc-wrap-bumper">void <a href="#a5e1f63034a96a5a79cef6da412efd203" class="m-doc-self">clear</a>(</span><span class="m-doc-wrap">)</span>
101109
</dt>
@@ -104,6 +112,10 @@ <h2><a href="#pub-methods">Public functions</a></h2>
104112
<span class="m-doc-wrap-bumper">auto <a href="#a8b3b0bee8762af654cfebd2bb2ee98ed" class="m-doc-self">num_tasks</a>(</span><span class="m-doc-wrap">) const -&gt; size_t</span>
105113
</dt>
106114
<dd>queries the number of tasks observed</dd>
115+
<dt id="a62ccf28199e35748903559848072fc29">
116+
<span class="m-doc-wrap-bumper">auto <a href="#a62ccf28199e35748903559848072fc29" class="m-doc-self">num_workers</a>(</span><span class="m-doc-wrap">) const -&gt; size_t</span>
117+
</dt>
118+
<dd>queries the number of observed workers</dd>
107119
</dl>
108120
</section>
109121
<section id="pri-methods">

docs/classtf_1_1WorkerInterface.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<h1>
4949
<span class="m-breadcrumb"><a href="namespacetf.html">tf</a>::<wbr/></span>WorkerInterface <span class="m-thin">class</span>
5050
</h1>
51-
<p>class <a href="classtf_1_1WorkerInterface.html" class="m-doc">WorkerInterface</a></p>
51+
<p>class to configure worker behavior in an executor</p>
5252
<nav class="m-block m-default">
5353
<h3>Contents</h3>
5454
<ul>
@@ -61,7 +61,7 @@ <h3>Contents</h3>
6161
</li>
6262
</ul>
6363
</nav>
64-
<p>The <a href="classtf_1_1WorkerInterface.html" class="m-doc">tf::<wbr />WorkerInterface</a> class lets users to interact with the executor to customize the thread behavior, such as calling custom methods before and after a worker enters and leaves the loop.</p><p>When you create an executor, it spawns a set of workers to run tasks. The interaction between the executor and its spawned workers looks like the following:</p><p>for(size_t n=0; n&lt;num_workers; n++) { create_thread([](<a href="classtf_1_1Worker.html" class="m-doc">Worker</a>&amp; worker)</p><p>pre-processing executor-specific worker information ...</p><p>enter the scheduling loop Here, <a href="classtf_1_1WorkerInterface.html#a41c3b931a36bde8eff4aa8d375e8888a" class="m-doc">WorkerInterface::<wbr />scheduler_prologue</a> is invoked, if any</p><pre>while(1) {
64+
<p>The <a href="classtf_1_1WorkerInterface.html" class="m-doc">tf::<wbr />WorkerInterface</a> class lets users interact with the executor to customize the worker behavior, such as calling custom methods before and after a worker enters and leaves the loop. When you create an executor, it spawns a set of workers to run tasks. The interaction between the executor and its spawned workers looks like the following:</p><p>for(size_t n=0; n&lt;num_workers; n++) { create_thread([](<a href="classtf_1_1Worker.html" class="m-doc">Worker</a>&amp; worker)</p><p>pre-processing executor-specific worker information ...</p><p>enter the scheduling loop Here, <a href="classtf_1_1WorkerInterface.html#a41c3b931a36bde8eff4aa8d375e8888a" class="m-doc">WorkerInterface::<wbr />scheduler_prologue</a> is invoked, if any</p><pre>while(1) {
6565
perform_work_stealing_algorithm();
6666
if(stop) {
6767
break;
@@ -109,6 +109,7 @@ <h3>
109109
</tr>
110110
</tbody>
111111
</table>
112+
<p>The method is called by the constructor of an executor.</p>
112113
</div></section>
113114
<section class="m-doc-details" id="a3e6d68fd4041f433d1b7ca9e5786b57c"><div>
114115
<h3>
@@ -131,6 +132,7 @@ <h3>
131132
</tr>
132133
</tbody>
133134
</table>
135+
<p>The method is called by the constructor of an executor.</p>
134136
</div></section>
135137
</section>
136138
</div>

0 commit comments

Comments
 (0)