{"id":10907,"date":"2025-08-11T08:45:45","date_gmt":"2025-08-11T08:45:45","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10907"},"modified":"2025-08-11T16:20:24","modified_gmt":"2025-08-11T16:20:24","slug":"data-parallel-types-algorithms","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/data-parallel-types-algorithms\/","title":{"rendered":"Data-Parallel Types: Algorithms"},"content":{"rendered":"\n<p>The data-parallel types library has four special algorithms for SIMD vectors.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"755\" height=\"509\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/06\/Time26ConcurrencySimd-1.png\" alt=\"\" class=\"wp-image-10788\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/06\/Time26ConcurrencySimd-1.png 755w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/06\/Time26ConcurrencySimd-1-300x202.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/06\/Time26ConcurrencySimd-1-705x475.png 705w\" sizes=\"auto, (max-width: 755px) 100vw, 755px\" \/><\/figure>\n\n\n\n<p>The four special algorithms are<code> min, max, minmax<\/code>, and <code>clamp<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>min, max, <\/code>and <code>minmax<\/code><\/h2>\n\n\n\n<p>The two algorithms <code>min <\/code>and <code>max <\/code>have in common that they each accept two SIMD vectors and return a SIMD vector. This contains the element-wise minimum or maximum of the input vectors. The <code>minmax <\/code>algorithm also takes two SIMD vectors and returns a pair of SIMD vectors. The first vector in the pair contains the element-wise minimum, the second the element-wise maximum of the input vectors.<\/p>\n\n\n\n<p>The following example shows the three algorithms in action:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ minmax.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;experimental\/simd&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iomanip&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">namespace<\/span> stdx <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>experimental;\n \n<span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">println<\/span>(<span style=\"color: #006699; font-weight: bold\">auto<\/span> rem, <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> v) {\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> rem <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;: &quot;<\/span>;\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">!=<\/span> v.size(); <span style=\"color: #555555\">++<\/span>i)\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>setw(<span style=\"color: #FF6600\">2<\/span>) <span style=\"color: #555555\">&lt;&lt;<\/span> v[i] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n}\n\n<span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">printPairs<\/span>(<span style=\"color: #006699; font-weight: bold\">auto<\/span> rem, <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> v1) {\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> rem <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;: &quot;<\/span>;\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">!=<\/span> v1.first.size(); <span style=\"color: #555555\">++<\/span>i)\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;(&#39;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> v1.first[i] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;, &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> v1.second[i] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;)&#39;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n}\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n\n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> a{[](<span style=\"color: #007788; font-weight: bold\">int<\/span> i) {\n        <span style=\"color: #006699; font-weight: bold\">static<\/span> constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> c <span style=\"color: #555555\">=<\/span> {<span style=\"color: #FF6600\">10<\/span>, <span style=\"color: #FF6600\">9<\/span>, <span style=\"color: #FF6600\">8<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">6<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">3<\/span>};\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> c.begin()[i];\n    }};\n    println(<span style=\"color: #CC3300\">&quot;a&quot;<\/span>, a);\n    \n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> b{[](<span style=\"color: #007788; font-weight: bold\">int<\/span> i) {\n        <span style=\"color: #006699; font-weight: bold\">static<\/span> constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> c <span style=\"color: #555555\">=<\/span> {<span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #FF6600\">6<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">8<\/span>, <span style=\"color: #FF6600\">9<\/span>, <span style=\"color: #FF6600\">10<\/span>,};\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> c.begin()[i];\n    }};\n    println(<span style=\"color: #CC3300\">&quot;b&quot;<\/span>, b);\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n   <span style=\"color: #006699; font-weight: bold\">auto<\/span> minimum <span style=\"color: #555555\">=<\/span> stdx<span style=\"color: #555555\">::<\/span>min(a, b);\n   println(<span style=\"color: #CC3300\">&quot;minimum&quot;<\/span>, minimum);\n\n   <span style=\"color: #006699; font-weight: bold\">auto<\/span> maximum <span style=\"color: #555555\">=<\/span> stdx<span style=\"color: #555555\">::<\/span>max(a, b);\n   println(<span style=\"color: #CC3300\">&quot;maximum&quot;<\/span>, maximum);\n\n   <span style=\"color: #0099FF; font-style: italic\">\/*<\/span>\n<span style=\"color: #0099FF; font-style: italic\">   auto minmax = stdx::minmax(a, b);<\/span>\n<span style=\"color: #0099FF; font-style: italic\">   printPairs(&quot;minmax&quot;, minmax);<\/span>\n<span style=\"color: #0099FF; font-style: italic\">   *\/<\/span>\n\n}\n<\/pre><\/div>\n\n\n\n<p>I use the SIMD vectors <code>a <\/code>and <code>b <\/code>as input vectors. These are initialized specially. To do this, I create an initialization list <code>c <\/code>in the lambda function that returns an iterator to it.<br>The following screenshot shows the output of the program:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"540\" height=\"220\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/minmax.png\" alt=\"\" class=\"wp-image-10909\" style=\"width:350px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/minmax.png 540w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/minmax-300x122.png 300w\" sizes=\"auto, (max-width: 540px) 100vw, 540px\" \/><\/figure>\n\n\n\n<p>You may be wondering why I commented out the use of the minmax algorithm. The reason is simple. I couldn&#8217;t compile the line<code> stdx::minmax(a, b) <\/code>with either the GCC or clang compilers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>clamp<\/code><\/h2>\n\n\n\n<p><code>std::datapar::clamp <\/code>applies the <code><a href=\"https:\/\/cppreference.com\/w\/cpp\/algorithm\/clamp.html\">std::clamp <\/a><\/code>function to the SIMD vector element by element. Each element is clamped to a minimum and maximum limit.<br>The following program is based on an example from cppreference:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ clamp.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;cstddef&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;cstdint&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;experimental\/simd&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iomanip&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">namespace<\/span> stdx <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>experimental;\n \n<span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">println<\/span>(<span style=\"color: #006699; font-weight: bold\">auto<\/span> rem, <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> v) {\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> rem <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;: &quot;<\/span>;\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">!=<\/span> v.size(); <span style=\"color: #555555\">++<\/span>i)\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>setw(<span style=\"color: #FF6600\">4<\/span>) <span style=\"color: #555555\">&lt;&lt;<\/span> v[i] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n}\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;INT8_MIN: &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> INT8_MIN <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;INT8_MAX: &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> INT8_MAX <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;UINT8_MAX: &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> UINT8_MAX <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> a{[](<span style=\"color: #007788; font-weight: bold\">int<\/span> i) {\n        <span style=\"color: #006699; font-weight: bold\">static<\/span> constexpr <span style=\"color: #006699; font-weight: bold\">auto<\/span> c <span style=\"color: #555555\">=<\/span> {<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">129<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">128<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">0<\/span>, <span style=\"color: #FF6600\">42<\/span>, <span style=\"color: #FF6600\">127<\/span>, <span style=\"color: #FF6600\">128<\/span>, <span style=\"color: #FF6600\">255<\/span>};\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> c.begin()[i];\n    }};\n    println(<span style=\"color: #CC3300\">&quot;a&quot;<\/span>, a);\n \n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> lo1{INT8_MIN};\n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> hi1{INT8_MAX};\n    <span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #006699; font-weight: bold\">auto<\/span> b <span style=\"color: #555555\">=<\/span> stdx<span style=\"color: #555555\">::<\/span>clamp(a, lo1, hi1);\n    println(<span style=\"color: #CC3300\">&quot;b&quot;<\/span>, b);\n \n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> lo2{<span style=\"color: #FF6600\">0<\/span>};\n    stdx<span style=\"color: #555555\">::<\/span>fixed_size_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, <span style=\"color: #FF6600\">8<\/span><span style=\"color: #555555\">&gt;<\/span> hi2{UINT8_MAX};\n    <span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #006699; font-weight: bold\">auto<\/span> c <span style=\"color: #555555\">=<\/span> stdx<span style=\"color: #555555\">::<\/span>clamp(a, lo2, hi2);\n    println(<span style=\"color: #CC3300\">&quot;c&quot;<\/span>, c);\n\n}\n<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"280\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/clamp.png\" alt=\"\" class=\"wp-image-10914\" style=\"width:350px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/clamp.png 720w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/clamp-300x117.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/clamp-705x274.png 705w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/figure>\n\n\n\n<p>It is nice to see in the output of the SIMD vector <code>b <\/code>how the values of the SIMD vector <code>a <\/code>are mapped to the boundary values <code>INT8_MIN <\/code>and <code>INT8_MAX<\/code>. In SIMD vector <code>c<\/code>, on the other hand, the boundary values <code>0 <\/code>and <code>UINT8_MAX <\/code>are used.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>Now it&#8217;s time for my second iteration through the new C++26 standard. I will focus primarily on the features that I did not cover in detail in my first iteration. I will start with contracts.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The data-parallel types library has four special algorithms for SIMD vectors. The four special algorithms are min, max, minmax, and clamp. min, max, and minmax The two algorithms min and max have in common that they each accept two SIMD vectors and return a SIMD vector. This contains the element-wise minimum or maximum of the [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":10788,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[559],"tags":[566],"class_list":["post-10907","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c26-blog","tag-data-parallel-types"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10907","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=10907"}],"version-history":[{"count":7,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10907\/revisions"}],"predecessor-version":[{"id":11013,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10907\/revisions\/11013"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/10788"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=10907"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10907"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}