<para>A partitioning algorithm allows applications to optimize parallel algorithms using different scheduling methods, such as static partitioning, dynamic partitioning, and guided partitioning.</para><sect1id="PartitioningAlgorithm_1DefineAPartitionerForParallelAlgorithms">
<title>Define a Partitioner for Parallel Algorithms</title>
<para>A partitioner defines how to partition and distribute iterations to different workers when running parallel algorithms in Taskflow, such as <refrefid="classtf_1_1FlowBuilder_1a025717373e424a6ccf9a61163bdaa585"kindref="member">tf::Taskflow::for_each</ref> and <refrefid="classtf_1_1FlowBuilder_1a822a75c597ae42cacc28d6f8cefb8c7c"kindref="member">tf::Taskflow::transform</ref>. The following example shows how to create parallel-iteration tasks with different execution policies:</para><para><programlistingfilename=".cpp"><codeline><highlightclass="normal"><refrefid="cpp/container/vector"kindref="compound"external="/home/twhuang/Code/taskflow/doxygen/cppreference-doxygen-web.tag.xml">std::vector<int></ref><sp/>data<sp/>=<sp/>{1,<sp/>2,<sp/>3,<sp/>4,<sp/>5,<sp/>6,<sp/>7,<sp/>8,<sp/>9,<sp/>10}</highlight></codeline>
</programlisting></para><para>Each partitioner has a specific algorithm to partition iterations into a set of <emphasis>chunks</emphasis> and distribute chunks to workers. A chunk is the basic unit of work that will be run by a worker during the execution of parallel iterations. The following figure illustrates the scheduling diagram for three major partitioners, <refrefid="classtf_1_1StaticPartitioner"kindref="compound">tf::StaticPartitioner</ref>, <refrefid="classtf_1_1DynamicPartitioner"kindref="compound">tf::DynamicPartitioner</ref>, and <refrefid="classtf_1_1GuidedPartitioner"kindref="compound">tf::GuidedPartitioner</ref>:</para><para><imagetype="html"name="parallel_for_partition_algorithms.png"></image>
</para><para>Depending on applications, partitioning algorithms can impact the performance a lot. For example, if a parallel-iteration workload contains a regular work unit per iteration, <refrefid="classtf_1_1StaticPartitioner"kindref="compound">tf::StaticPartitioner</ref> may deliver the best performance. On the other hand, if the work unit per iteration is irregular and unbalanced, <refrefid="classtf_1_1GuidedPartitioner"kindref="compound">tf::GuidedPartitioner</ref> or <refrefid="classtf_1_1DynamicPartitioner"kindref="compound">tf::DynamicPartitioner</ref> can outperform <refrefid="classtf_1_1StaticPartitioner"kindref="compound">tf::StaticPartitioner</ref>.</para><para><simplesectkind="note"><para>By default, all parallel algorithms in Taskflow use tf::DefaultExecutionPolicy, which is based on guided scheduling via <refrefid="classtf_1_1GuidedPartitioner"kindref="compound">tf::GuidedPartitioner</ref>.</para></simplesect>
<para>Static partitioner splits iterations into <computeroutput>iter_size/chunk_size</computeroutput> chunks and distribute chunks to workers in order. If no chunk size is given (<computeroutput>chunk_size</computeroutput> is <computeroutput>1</computeroutput>), Taskflow will partition iterations into chunks that are approximately equal in size. The following code creates a static partitioner with chunk size equal to 100:</para><para><programlistingfilename=".cpp"><codeline><highlightclass="normal"><refrefid="classtf_1_1StaticPartitioner"kindref="compound">tf::StaticPartitioner</ref><sp/>static_partitioner(100);</highlight></codeline>
<para>Dynamic partitioner splits iterations into <computeroutput>iter_size/chunk_size</computeroutput> chunks and distribute chunks to workers without any specific order. The default chunk size is <computeroutput>1</computeroutput>, if not specified. The following code creates a dynamic partitioner with chunk size equal to 2:</para><para><programlistingfilename=".cpp"><codeline><highlightclass="normal"><refrefid="classtf_1_1DynamicPartitioner"kindref="compound">tf::DynamicPartitioner</ref><sp/>dynamic_partitioner(2);</highlight></codeline>
<para>Guided partitioner dynamically decides the chunk size. The size of a chunk is proportional to the number of unassigned iterations divided by the number of the threads, and the size will gradually decrease to the specified chunk size (default <computeroutput>1</computeroutput>). The last chunk may be smaller than the specified chunk size. The following code creates a guided partitioner with chunk size equal to 10:</para><para><programlistingfilename=".cpp"><codeline><highlightclass="normal"><refrefid="classtf_1_1GuidedPartitioner"kindref="compound">tf::GuidedPartitioner</ref><sp/>guided_partitioner(10);</highlight></codeline>
</programlisting></para><para>In most situations, guided partitioner can achieve decent performance due to adaptive parallelism, especially for those with irregular and unbalanced workload per iteration. As a result, guided partitioner is used as the default partitioner for our parallel algorithms. </para></sect1>