{"id":10871,"date":"2025-07-14T09:16:39","date_gmt":"2025-07-14T09:16:39","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10871"},"modified":"2025-07-14T09:16:40","modified_gmt":"2025-07-14T09:16:40","slug":"data-parallel-types-simd_mask","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/data-parallel-types-simd_mask\/","title":{"rendered":"Data-Parallel Types: simd_mask"},"content":{"rendered":"\n<p>Thanks to <code>simd_mask<\/code>, conditional execution of operations on data-parallel types is possible.<\/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>Unfortunately, in my last article,<a href=\"https:\/\/www.modernescpp.com\/index.php\/data-parallel-types-a-first-example\/\"> Data-Parallel Types \u2013 A First Example<\/a>, I  forgot to introduce one of the new library functions. I will make up for that in this article.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where Expression<\/h2>\n\n\n\n<p>The new keyword <code>where<\/code> creates a so-called where expression. This allows the elements of a SIMD vector to be addressed conditionally.<br>The following example illustrates this behavior:<\/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\">\/\/ where.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;experimental\/simd&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string_view&gt;<\/span>\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>(std<span style=\"color: #555555\">::<\/span>string_view name, <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span><span style=\"color: #555555\">&amp;<\/span> a)\n{\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> name <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{}; i <span style=\"color: #555555\">!=<\/span> std<span style=\"color: #555555\">::<\/span>size(a); <span style=\"color: #555555\">++<\/span>i)\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> a[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: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">A<\/span><span style=\"color: #555555\">&gt;<\/span>\nstdx<span style=\"color: #555555\">::<\/span>simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, A<span style=\"color: #555555\">&gt;<\/span> my_abs(stdx<span style=\"color: #555555\">::<\/span>simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span>, A<span style=\"color: #555555\">&gt;<\/span> x)\n{\n    where(x <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">0<\/span>, x) <span style=\"color: #555555\">=<\/span> <span style=\"color: #555555\">-<\/span>x; <span style=\"color: #0099FF; font-style: italic\">\/\/ Set elements where x is negative to their absolute value       <\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> x;\n}\n \n<span style=\"color: #007788; font-weight: bold\">int<\/span> main()\n{\n    <span style=\"color: #006699; font-weight: bold\">const<\/span> stdx<span style=\"color: #555555\">::<\/span>native_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> a <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">1<\/span>;\n    println(<span style=\"color: #CC3300\">&quot;a&quot;<\/span>, a);\n \n    <span style=\"color: #006699; font-weight: bold\">const<\/span> stdx<span style=\"color: #555555\">::<\/span>native_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> b([](<span style=\"color: #007788; font-weight: bold\">int<\/span> i) { <span style=\"color: #006699; font-weight: bold\">return<\/span> i <span style=\"color: #555555\">-<\/span> <span style=\"color: #FF6600\">2<\/span>; });\n    println(<span style=\"color: #CC3300\">&quot;b&quot;<\/span>, b);\n \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> a <span style=\"color: #555555\">+<\/span> b;\n    println(<span style=\"color: #CC3300\">&quot;c&quot;<\/span>, c);\n \n    <span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #006699; font-weight: bold\">auto<\/span> d <span style=\"color: #555555\">=<\/span> my_abs(c);\n    println(<span style=\"color: #CC3300\">&quot;d&quot;<\/span>, d);\n \n}\n<\/pre><\/div>\n\n\n\n<p>The <code>where<\/code> function is used in the <code>my_abs<\/code> function:<code> where(x &lt; 0, x) = -x<\/code>; . This expression causes all elements of the SIMD vector that are less than zero to be set to their absolute value. 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=\"220\" height=\"160\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/where.png\" alt=\"\" class=\"wp-image-10875\" style=\"width:150px\"\/><\/figure>\n\n\n\n<p>In this case, SSE2 commands are used. The SIMD vector is 128 bits in size.<\/p>\n\n\n\n<p>The <code>where <\/code>expression can be parameterized with a <code>bool <\/code>expression or a <code>simd_mask<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><code>simd_mask<\/code><\/h2>\n\n\n\n<p>This allows the previous program <code>where.cpp<\/code> to also be implemented by using a <code>simd_mask<\/code>. The following program shows the application of the<code> simd_mask<\/code>.<\/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\">\/\/ whereMask.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;experimental\/simd&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;string_view&gt;<\/span>\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>(std<span style=\"color: #555555\">::<\/span>string_view name, <span style=\"color: #006699; font-weight: bold\">auto<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span><span style=\"color: #555555\">&amp;<\/span> a)\n{\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> std<span style=\"color: #555555\">::<\/span>boolalpha <span style=\"color: #555555\">&lt;&lt;<\/span> name <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{}; i <span style=\"color: #555555\">!=<\/span> std<span style=\"color: #555555\">::<\/span>size(a); <span style=\"color: #555555\">++<\/span>i)\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> a[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 \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>()\n{\n    <span style=\"color: #006699; font-weight: bold\">const<\/span> stdx<span style=\"color: #555555\">::<\/span>native_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> a <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">1<\/span>;\n    println(<span style=\"color: #CC3300\">&quot;a&quot;<\/span>, a);\n \n    <span style=\"color: #006699; font-weight: bold\">const<\/span> stdx<span style=\"color: #555555\">::<\/span>native_simd<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> b([](<span style=\"color: #007788; font-weight: bold\">int<\/span> i) { <span style=\"color: #006699; font-weight: bold\">return<\/span> i <span style=\"color: #555555\">-<\/span> <span style=\"color: #FF6600\">2<\/span>; });\n    println(<span style=\"color: #CC3300\">&quot;b&quot;<\/span>, b);\n \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> a <span style=\"color: #555555\">+<\/span> b;\n    println(<span style=\"color: #CC3300\">&quot;c&quot;<\/span>, c);\n \n    <span style=\"color: #006699; font-weight: bold\">const<\/span> stdx<span style=\"color: #555555\">::<\/span>native_simd_mask x <span style=\"color: #555555\">=<\/span> c <span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #FF6600\">0<\/span>; \n    println(<span style=\"color: #CC3300\">&quot;x&quot;<\/span>, x);\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> d  <span style=\"color: #555555\">=<\/span> c;\n    where(x, d) <span style=\"color: #555555\">*=<\/span> <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">1<\/span>; \n    println(<span style=\"color: #CC3300\">&quot;d&quot;<\/span>, d);\n \n}\n<\/pre><\/div>\n\n\n\n<p><br>I would like to begin my explanation with the last five lines of the <code>main<\/code> function. First, I create the <code>simd_mask x<\/code> by applying the predicate<code>  c &lt; 0<\/code> to each element of the SIMD vector <code>c<\/code>. The mask <code>x <\/code>has the same length as the SIMD vector, but only contains truth values. To ensure that these truth values are displayed as <code>true <\/code>or <code>false<\/code> and not as<code> 1 <\/code>or<code> 0<\/code>, I have added the stream manipulator <code>std::boolalpha<\/code> to the <code>println<\/code> function. In addition, I have to initialize the SIMD vector <code>d<\/code> with <code>c<\/code>, since <code>c<\/code> is constant. Now the where expression  <code>where(x, d) *= -1 <\/code>can be applied to<code> d<\/code>. Each element of the SIMD vector<code> d<\/code> is negated if the mask has the value true.<\/p>\n\n\n\n<p>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=\"480\" height=\"220\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/whereMask.png\" alt=\"\" class=\"wp-image-10882\" style=\"width:300px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/whereMask.png 480w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/07\/whereMask-300x138.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/figure>\n\n\n\n<p>The data type <code>simd_mask<\/code> is very similar to the data type <code>simd<\/code>. The main difference is that <code>simd<\/code> can accept all standard integer types, character types, and the types <code>float<\/code> and <code>double<\/code>. In contrast, <code>simd_mask <\/code>only supports Boolean values.<\/p>\n\n\n\n<p>Here is the definition of <code>simd_mask<\/code>:<\/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: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> Bytes, <span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">Abi<\/span><span style=\"color: #555555\">&gt;<\/span> \n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">basic_simd_mask<\/span>\n<\/pre><\/div>\n\n\n\n<p>The <code>Abi <\/code>tag determines the number of elements and their memory. For the sake of completeness, here are the ABI tags again:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>scalar<\/code>: storing a single element<\/li>\n\n\n\n<li><code>fixed_size<\/code>: storing a specified number of elements<\/li>\n\n\n\n<li><code>compatible<\/code>: ensures ABI compatibility<\/li>\n\n\n\n<li><code>native<\/code>: most efficient<\/li>\n\n\n\n<li><code>max_fixed_size<\/code>: maximum number of elements guaranteed to be supported by <code>fixed_size<\/code><\/li>\n<\/ul>\n\n\n\n<p><br>Similar to <code>simd<\/code>, <code>simd_mask<\/code> also has two aliases:<\/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: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #007788; font-weight: bold\">size_t<\/span> Bytes, <span style=\"color: #007788; font-weight: bold\">int<\/span> N <span style=\"color: #555555\">&gt;<\/span> \n<span style=\"color: #006699; font-weight: bold\">using<\/span> fixed_size_simd_mask <span style=\"color: #555555\">=<\/span> simd_mask<span style=\"color: #555555\">&lt;<\/span>Bytes, simd_abi<span style=\"color: #555555\">::<\/span>fixed_size<span style=\"color: #555555\">&lt;<\/span>N<span style=\"color: #555555\">&gt;&gt;<\/span> \n\n<span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span> <span style=\"color: #007788; font-weight: bold\">size_t<\/span> Bytes <span style=\"color: #555555\">&gt;<\/span> \n<span style=\"color: #006699; font-weight: bold\">using<\/span> native_simd_mask <span style=\"color: #555555\">=<\/span>  simd_mask<span style=\"color: #555555\">&lt;<\/span>Bytes, simd_abi<span style=\"color: #555555\">::<\/span>native<span style=\"color: #555555\">&lt;<\/span>Bytes<span style=\"color: #555555\">&gt;&gt;<\/span>\n<\/pre><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s next?<\/h2>\n\n\n\n<p>In what will be my last article on data-parallel types for the time being, I would like to discuss the special functions for these types.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Thanks to simd_mask, conditional execution of operations on data-parallel types is possible. Unfortunately, in my last article, Data-Parallel Types \u2013 A First Example, I forgot to introduce one of the new library functions. I will make up for that in this article. Where Expression The new keyword where creates a so-called where expression. This allows [&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-10871","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\/10871","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=10871"}],"version-history":[{"count":12,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10871\/revisions"}],"predecessor-version":[{"id":10887,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10871\/revisions\/10887"}],"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=10871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}