76 lines
8.6 KiB
XML
76 lines
8.6 KiB
XML
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||
|
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.9.1" xml:lang="en-US">
|
||
|
<compounddef id="fibonacci" kind="page">
|
||
|
<compoundname>fibonacci</compoundname>
|
||
|
<title>Fibonacci Number</title>
|
||
|
<tableofcontents>
|
||
|
<tocsect>
|
||
|
<name>Problem Formulation</name>
|
||
|
<reference>fibonacci_1FibonacciNumberProblem</reference>
|
||
|
</tocsect>
|
||
|
<tocsect>
|
||
|
<name>Recursive Fibonacci Parallelism</name>
|
||
|
<reference>fibonacci_1RecursiveFibonacciParallelism</reference>
|
||
|
</tocsect>
|
||
|
</tableofcontents>
|
||
|
<briefdescription>
|
||
|
</briefdescription>
|
||
|
<detaileddescription>
|
||
|
<para>We study the classic problem, <emphasis>Fibonacci Number</emphasis>, to demonstrate the use of recursive task parallelism.</para>
|
||
|
<sect1 id="fibonacci_1FibonacciNumberProblem">
|
||
|
<title>Problem Formulation</title>
|
||
|
<para>In mathematics, the Fibonacci numbers, commonly denoted <computeroutput>F(n)</computeroutput>, form a sequence such that each number is the sum of the two preceding ones, starting from 0 and 1.</para>
|
||
|
<para><computeroutput>0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...</computeroutput></para>
|
||
|
<para>A common solution for computing fibonacci numbers is <emphasis>recursion</emphasis>.</para>
|
||
|
<para><programlisting filename=".cpp"><codeline><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>fib(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>n)<sp/>{</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal">(n<sp/><<sp/>2)<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>n;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>fib(n-1)<sp/>+<sp/>fib(n-2);</highlight></codeline>
|
||
|
<codeline><highlight class="normal">}</highlight></codeline>
|
||
|
</programlisting></para>
|
||
|
</sect1>
|
||
|
<sect1 id="fibonacci_1RecursiveFibonacciParallelism">
|
||
|
<title>Recursive Fibonacci Parallelism</title>
|
||
|
<para>We use <ref refid="classtf_1_1Subflow" kindref="compound">tf::Subflow</ref> to recursively compute fibonacci numbers in parallel.</para>
|
||
|
<para><programlisting filename=".cpp"><codeline><highlight class="preprocessor">#include<sp/><<ref refid="taskflow_8hpp" kindref="compound">taskflow/taskflow.hpp</ref>></highlight><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>spawn(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>n,<sp/><ref refid="classtf_1_1Subflow" kindref="compound">tf::Subflow</ref>&<sp/>sbf)<sp/>{</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(n<sp/><<sp/>2)<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>n;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>res1,<sp/>res2;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>sbf.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([&res1,<sp/>n]<sp/>(<ref refid="classtf_1_1Subflow" kindref="compound">tf::Subflow</ref>&<sp/>sbf)<sp/>{<sp/>res1<sp/>=<sp/>spawn(n<sp/>-<sp/>1,<sp/>sbf);<sp/>}<sp/>)</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/>.name(<ref refid="namespacetf_1a9ca58dc6c666698cc7373eb0262140ef" kindref="member">std::to_string</ref>(n-1));<sp/><sp/></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>sbf.<ref refid="classtf_1_1FlowBuilder_1a60d7a666cab71ecfa3010b2efb0d6b57" kindref="member">emplace</ref>([&res2,<sp/>n]<sp/>(<ref refid="classtf_1_1Subflow" kindref="compound">tf::Subflow</ref>&<sp/>sbf)<sp/>{<sp/>res2<sp/>=<sp/>spawn(n<sp/>-<sp/>2,<sp/>sbf);<sp/>}<sp/>)</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/>.name(<ref refid="namespacetf_1a9ca58dc6c666698cc7373eb0262140ef" kindref="member">std::to_string</ref>(n-2));</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>sbf.<ref refid="classtf_1_1Subflow_1a59fcac1323e70d920088dd37bd0be245" kindref="member">join</ref>();</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>res1<sp/>+<sp/>res2;</highlight></codeline>
|
||
|
<codeline><highlight class="normal">}</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>argc,<sp/></highlight><highlight class="keywordtype">char</highlight><highlight class="normal">*<sp/>argv[])<sp/>{</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>N<sp/>=<sp/>5;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>res;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Executor" kindref="compound">tf::Executor</ref><sp/>executor;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><ref refid="classtf_1_1Taskflow" kindref="compound">tf::Taskflow</ref><sp/>taskflow(</highlight><highlight class="stringliteral">"fibonacci"</highlight><highlight class="normal">);</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>taskflow.emplace([&res,<sp/>N]<sp/>(<ref refid="classtf_1_1Subflow" kindref="compound">tf::Subflow</ref>&<sp/>sbf)<sp/>{<sp/>res<sp/>=<sp/>spawn(N,<sp/>sbf);<sp/>})</highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>.name(<ref refid="namespacetf_1a9ca58dc6c666698cc7373eb0262140ef" kindref="member">std::to_string</ref>(N));</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>executor.<ref refid="classtf_1_1Executor_1a8d08f0cb79e7b3780087975d13368a96" kindref="member">run</ref>(taskflow).wait();</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/>taskflow.dump(<ref refid="cpp/io/basic_ostream" kindref="compound" external="/home/thuang295/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">std::cout</ref>);</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/><ref refid="cpp/io/basic_ostream" kindref="compound" external="/home/thuang295/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">std::cout</ref><sp/><<<sp/></highlight><highlight class="stringliteral">"Fib["</highlight><highlight class="normal"><sp/><<<sp/>N<sp/><<<sp/></highlight><highlight class="stringliteral">"]:<sp/>"</highlight><highlight class="normal"><sp/><<<sp/>res<sp/><<<sp/><ref refid="cpp/io/manip/endl" kindref="compound" external="/home/thuang295/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">std::endl</ref>;</highlight></codeline>
|
||
|
<codeline><highlight class="normal"></highlight></codeline>
|
||
|
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>0;</highlight></codeline>
|
||
|
<codeline><highlight class="normal">}</highlight></codeline>
|
||
|
</programlisting></para>
|
||
|
<para>The spawned taskflow graph for computing up to the fifth fibonacci number is shown below:</para>
|
||
|
<para><dotfile name="/home/thuang295/Code/taskflow/doxygen/images/fibonacci_7.dot"></dotfile>
|
||
|
</para>
|
||
|
<para>Even if recursive dynamic tasking or subflows are possible, the recursion depth may not be too deep or it can cause stack overflow. </para>
|
||
|
</sect1>
|
||
|
</detaileddescription>
|
||
|
<location file="doxygen/examples/fibonacci.dox"/>
|
||
|
</compounddef>
|
||
|
</doxygen>
|