{"id":488795,"date":"2026-07-28T06:00:24","date_gmt":"2026-07-28T06:00:24","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=488795"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=488795","title":{"rendered":"a[mask] = f(a[mask]) \u043d\u0430 NEON. compress \u0432\u043c\u0435\u0441\u0442\u043e blend"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430<\/h3>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043a \u0442\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0434 \u0443\u0441\u043b\u043e\u0432\u0438\u0435:<\/p>\n<pre><code>for (size_t i = 0; i &lt; n; ++i)    if (mask(a[i])) a[i] = f(a[i]);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/h4>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435:<\/p>\n<ul>\n<li>\n<p><code>a[i] \u2208 (0, 1)<\/code>, <code>thd \u2208 (0, 1)<\/code>, <code>mask = a[i] &lt; thd<\/code>; \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u044b (\u043a\u0440\u043e\u043c\u0435 \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0430\u0442\u044c\u0438)<\/p>\n<\/li>\n<li>\n<p><code>f<\/code> \u0438\u0437 <code>sqrt<\/code>, <code>frfrexp<\/code> (\u043c\u0430\u043d\u0442\u0438\u0441\u0441\u0430 \u0447\u0438\u0441\u043b\u0430), <code>sin<\/code> 3.5 ULP, <code>sin<\/code> 1 ULP, <code>pow<\/code> 1 ULP (\u0438\u0437 SLEEF)<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b \u0432 \u043b\u044f\u043c\u0431\u0434\u0443 \u0441 <code>always_inline<\/code>, \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0437\u0430\u0438\u043d\u043b\u0430\u0439\u043d\u0438\u0442\u044c\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 <code>n<\/code> \u043a\u0440\u0430\u0442\u0435\u043d \u0432\u0441\u0435\u043c \u0430\u043d\u0440\u043e\u043b\u043b\u0430\u043c, \u0442\u0430\u0439\u043b\u0430\u043c \u0438\u0442\u0434, \u0445\u0432\u043e\u0441\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u043e (BSL\/\u0441\u043a\u0430\u043b\u044f\u0440)<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 <code>*<\/code> &#8212; \u043b\u0443\u0447\u0448\u0438\u0439, \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f &#8212; GiB\/s<\/p>\n<\/li>\n<li>\n<p>\u0427\u0438\u0441\u043b\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u043d\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u0438\u0437-\u0437\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0435\u0431\u043b\u044e\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0431\u0435\u043d\u0447\u0438: Apple M5; clang++ -O3 -std=c++23 -march=native; GiB\/s = (n * 4 bytes) \/ time, \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0438\u0437 720 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 (\u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u0432 \u043c\u0435\u043d\u044f\u044e\u0449\u0435\u043c\u0441\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e); n=1e7 + 2432<\/p>\n<\/li>\n<\/ul>\n<h3>BSL blend<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u044c (\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043b\u0435\u0433\u043a\u0430\u044f \u0438\u043b\u0438 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0441\u043e\u043a\u0430\u044f), \u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d:<\/p>\n<pre><code>    template &lt;bool Skip&gt;    void bsl(float* dst, const size_t n, auto f, auto mask) {        for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint32x4_t, 4&gt; m;            for (size_t j = 0; j &lt; 4; ++j) m[j] = mask(v[j]);            if constexpr (Skip) {                if (vmaxvq_u32(vaddq_u32(vaddq_u32(m[0], m[1]), vaddq_u32(m[2], m[3]))) == 0) continue;            }            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(dst + i + 4 * j, vbslq_f32(m[j], f(v[j]), v[j]));        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043c\u0430\u0441\u043a\u0435. Skip &#8212; \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0436\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u0441\u043e\u043a \u043f\u043e\u043c\u043e\u0436\u0435\u0442, \u043d\u043e \u0438\u043d\u0430\u0447\u0435 \u043c\u0438\u0441\u043f\u0440\u0435\u0434\u0438\u043a\u0442\u044b \u0443\u0431\u044c\u044e\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0414\u0430\u043b\u044c\u0448\u0435 \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e bsl \u043d\u0430 \u0442\u044f\u0436\u0435\u043b\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<h3>Detour<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0435\u0435, \u0441\u043e\u0436\u043c\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 (compress), \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043d\u0438\u043c, \u0440\u0430\u0437\u043e\u0436\u043c\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e (expand).<\/p>\n<p>\u041d\u0430 avx512 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0432 \u043f\u0430\u0440\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043d\u043e \u043d\u0430 NEON &#8212; \u043d\u0435\u0442. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<pre><code>    constexpr double D = 0.845; \/\/ D \u0438 B \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u044b \u0431\u0443\u0434\u0443\u0442    constexpr double B = 0.3;    constexpr size_t tile = 4096;    constexpr std::array&lt;uint32_t, 4&gt; weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};    constexpr auto cps_tbl = compress_table();    constexpr auto exp_tbl = expand_table();    std::array&lt;float, tile + 16&gt; tmp;    std::array&lt;uint8_t, tile \/ 4 + 3&gt; s;    std::array&lt;uint16_t, tile \/ 4 + 3&gt; idx; \/\/ \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f    template &lt;bool Skip&gt;    size_t detour(float* dst, const size_t n, const auto w, auto f, auto mask) {        float* ptr = tmp.data();        for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint32x4_t, 4&gt; m;            for (size_t j = 0; j &lt; 4; ++j) m[j] = mask(v[j]);                        if constexpr (Skip)                if (vmaxvq_u32(vaddq_u32(vaddq_u32(m[0], m[1]), vaddq_u32(m[2], m[3]))) == 0) {                    s[i \/ 4] = s[i \/ 4 + 1] = s[i \/ 4 + 2] = s[i \/ 4 + 3] = 0;                    continue;                }                        std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) {                sk[j] = vaddvq_u32(vandq_u32(m[j], w));                s[i \/ 4 + j] = sk[j];            }            std::array&lt;size_t, 4&gt; off; off[0] = 0;            for (size_t j = 1; j &lt; 4; ++j) off[j] = off[j - 1] + (sk[j - 1] &gt;&gt; 4);             std::array&lt;uint8x16_t, 4&gt; index;            for (size_t j = 0; j &lt; 4; ++j) index[j] = vld1q_u8(cps_tbl[sk[j] &amp; 15].data());                        for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(ptr + off[j], vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(v[j]), index[j])));            ptr += off[3] + (sk[3] &gt;&gt; 4);        }        const size_t size = ptr - tmp.data();        if (size == 0) return size;                ptr = tmp.data();        for (size_t i = 0; i &lt; size; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(ptr + i + 4 * j);            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(ptr + i + 4 * j, f(v[j]));        }                for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) sk[j] = s[i \/ 4 + j];            std::array&lt;size_t, 4&gt; off{};            for (size_t j = 1; j &lt; 4; ++j) off[j] = off[j - 1] + (sk[j - 1] &gt;&gt; 4);             std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(ptr + off[j]);            std::array&lt;float32x4_t, 4&gt; a;            for (size_t j = 0; j &lt; 4; ++j) a[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint8x16_t, 4&gt; index;            for (size_t j = 0; j &lt; 4; ++j) index[j] = vld1q_u8(exp_tbl[sk[j] &amp; 15].data());            std::array&lt;uint8x16x2_t, 4&gt; tbl;            for (size_t j = 0; j &lt; 4; ++j) tbl[j] = {{vreinterpretq_u8_f32(v[j]), vreinterpretq_u8_f32(a[j])}};            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(dst + i + 4 * j, vreinterpretq_f32_u8(vqtbl2q_u8(tbl[j], index[j])));            ptr += off[3] + (sk[3] &gt;&gt; 4);        }        return size;    }    void tiled_detour(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        for (size_t i = 0; i &lt; n; i += tile)            detour&lt;false&gt;(dst + i, tile, w, f, mask);    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>compress \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u0442 \u0436\u0435 \u0447\u0442\u043e \u0438 \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/1055904\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>expand_table &#8212; \u0434\u043b\u044f true \u043b\u0435\u0439\u043d\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0436\u0430\u0442\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 (\u0431\u0430\u0439\u0442\u044b \u0438\u0437 <code>[0, 15]<\/code>), \u0430 \u0434\u043b\u044f false &#8212; \u0442\u0435 \u0436\u0435 \u0431\u0430\u0439\u0442\u044b + 16. \u041f\u043e\u0442\u043e\u043c tbl2 \u043f\u043e {\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435, \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435}, \u0432 \u043e\u0431\u0449\u0435\u043c \u0442\u043e\u0442 \u0436\u0435 \u0442\u0440\u044e\u043a, \u0447\u0442\u043e \u0438 \u0432 compress<\/p>\n<p>\u0418 \u0435\u0449\u0435:<\/p>\n<ul>\n<li>\n<p>\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0441\u043a\u0438\u043f\u0430\u0435\u0442\u0441\u044f expand \u043d\u0430 \u043f\u0443\u0441\u0442\u044b\u0445 \u0442\u0430\u0439\u043b\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>\u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0430\u0439\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0435\u0448<\/p>\n<\/li>\n<li>\n<p>\u042d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 <code>tile=4096<\/code> \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d.<\/p>\n<\/li>\n<li>\n<p><code>s<\/code> \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c addv<\/p>\n<\/li>\n<\/ul>\n<p>\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c BSL \u043e\u0442 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442. <code>sqrt 32.1<\/code>, <code>sin35 - 9.7<\/code>, <code>pow10 1.02<\/code>.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.1<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.2<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.3<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.4<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.5<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.6<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.7<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.8<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.9<\/p>\n<\/th>\n<th>\n<p align=\"left\">1<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">detour sqrt<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.03*<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.81<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.82<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.98<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.21<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.51<\/p>\n<\/td>\n<td>\n<p align=\"left\">13.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">13.24<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.71<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.30<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">detour sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.16*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.70*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.46*<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.71*<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.36*<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.25*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.35<\/p>\n<\/td>\n<td>\n<p align=\"left\">8.59<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.95<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.39<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.95<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">detour pow10<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.09*<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.83*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.13*<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.96*<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.31*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.60*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.39*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.22*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.10*<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.99<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u043b\u044f \u0434\u0435\u0448\u0435\u0432\u043e\u0433\u043e sqrt \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0433\u043e\u0434\u0435\u043d BSL (\u043a\u0440\u043e\u043c\u0435 thd = 0, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e), \u0430 \u0434\u043b\u044f \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0440\u043e\u0433\u043e\u0433\u043e pow &#8212; detour (\u0435\u0441\u043b\u0438 thd != 1, \u043a\u043e\u043d\u0435\u0447\u043d\u043e)<\/p>\n<h3>\u041a\u043e\u0433\u0434\u0430 \u043e\u043a\u0443\u043f\u0430\u0435\u0442\u0441\u044f detour<\/h3>\n<p>\u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043c:<\/p>\n<ul>\n<li>\n<p><code>B<\/code> &#8212; \u043e\u0432\u0435\u0440\u0445\u0435\u0434 BSL(<code>vld + vbsl + vst<\/code>) \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440.<\/p>\n<\/li>\n<li>\n<p><code>D<\/code> &#8212; \u043e\u0432\u0435\u0440\u0445\u0435\u0434 detour(\u0441\u0436\u0430\u0442\u0438\u0435 + \u0440\u0430\u0437\u0436\u0430\u0442\u0438\u0435) \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440.<\/p>\n<\/li>\n<li>\n<p><code>T<\/code> &#8212; \u0446\u0435\u043d\u0430 <code>f<\/code> \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440 (\u0441\u0447\u0438\u0442\u0430\u0435\u043c <code>\u0446\u0435\u043d\u0443 f &gt;&gt; \u0446\u0435\u043d\u044b mask<\/code>, \u0432\u043b\u0438\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u043b\u0438\u0431\u0440\u043e\u0432\u043a\u0438).<\/p>\n<\/li>\n<li>\n<p><code>d<\/code> &#8212; \u0434\u043e\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>BSL \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 <code>f<\/code> \u043a\u043e \u0432\u0441\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043c, \u0430 detour \u0442\u043e\u043b\u044c\u043a\u043e \u043a <code>d<\/code> &#8212; \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 <code>T * (1 - d)<\/code>. \u0417\u043d\u0430\u0447\u0438\u0442 detour \u0432\u044b\u0433\u043e\u0434\u0435\u043d \u043a\u043e\u0433\u0434\u0430 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u0435\u0442 <code>D - B<\/code>:<\/p>\n<p><code>T * (1 - d) &gt; D - B<\/code><\/p>\n<p>detour \u0432\u044b\u0433\u043e\u0434\u0435\u043d \u043a\u043e\u0433\u0434\u0430 <code>d<\/code> \u043c\u0435\u043d\u044c\u0448\u0435 <code>d_max = 1 - (D - B) \/ T<\/code>.<\/p>\n<p><code>B<\/code> \u0438 <code>D<\/code> &#8212; \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442 \u0436\u0435\u043b\u0435\u0437\u0430, \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b, \u043f\u043e\u043c\u0435\u0440\u0438\u043c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 (\u0443 \u043c\u0435\u043d\u044f &#8212; <code>B = 0.3<\/code>, <code>D = 0.845<\/code> ns\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440) <code>T<\/code> &#8212; \u0443\u0437\u043d\u0430\u0435\u043c \u0437\u0430 \u043f\u0435\u0440\u0432\u044b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u0439\u043b\u043e\u0432, \u043c\u0435\u0440\u044f\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b BSL. \u0410 \u043f\u043e \u043d\u0435\u043c\u0443 \u0443\u0437\u043d\u0430\u0435\u043c \u0438 <code>d_max<\/code>:<\/p>\n<pre><code>    template&lt;size_t tile&gt;    double bsl_calibrate(float* dst, const size_t len, auto f, auto mask) {        double ns = 1e18;        for (size_t i = 0; i &lt; len; i += tile) {            const auto st = std::chrono::high_resolution_clock::now();            bsl&lt;false&gt;(dst, tile, f, mask);            const auto ed = std::chrono::high_resolution_clock::now();            ns = std::min(ns, std::chrono::duration&lt;double, std::nano&gt;(ed - st).count());            dst += tile;        }        const double t = std::max(1e-9, ns \/ (tile \/ 4.0) - B);        return 1.0 - (D - B) \/ t;    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c:<\/p>\n<ul>\n<li>\n<p>\u044d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 4 \u0442\u0430\u0439\u043b\u0430 \u043f\u043e 2048 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>min \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432 \u043a \u0448\u0443\u043c\u0443 \u0447\u0435\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0430\u043b\u0438\u0431\u0440\u043e\u0432\u043a\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u0439\u043b\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u043c\u0435\u0440\u044f\u0435\u043c bsl, \u0432\u0435\u0434\u044c \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 <code>f<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e <code>T = t_bsl - B<\/code>.<\/p>\n<\/li>\n<li>\n<p>std::max \u0442\u0443\u0442 \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u043e\u0442 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 0 \u0438 \u043e\u0442 <code>t &lt; 0<\/code> \u043f\u0440\u0438 \u043e\u0447\u0435\u043d\u044c \u0434\u0435\u0448\u0435\u0432\u043e\u043c <code>T<\/code>.<\/p>\n<\/li>\n<\/ul>\n<h4>pilot v1<\/h4>\n<p>bsl \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435, \u043a\u043e\u0433\u0434\u0430 d_max &lt; 0:<\/p>\n<pre><code>    void pilot_v1(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        const float d_max = bsl_calibrate&lt;tile \/ 2&gt;(dst, 2 * tile, f, mask);        dst += 2 * tile;        for (size_t i = 2 * tile; i &lt; n; i += tile) {            if (d_max &lt; 0)                bsl&lt;false&gt;(dst, tile, f, mask);            else                detour&lt;false&gt;(dst, tile, w, f, mask);            dst += tile;        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">tiled detour sqrt<\/p>\n<\/th>\n<th>\n<p align=\"left\">pilot v1 sqrt<\/p>\n<\/th>\n<th>\n<p align=\"left\">BSL sqrt<\/p>\n<\/th>\n<th>\n<p align=\"left\">\n<\/th>\n<th>\n<p align=\"left\">tiled detour sin35<\/p>\n<\/th>\n<th>\n<p align=\"left\">pilot v1 sin35<\/p>\n<\/th>\n<th>\n<p align=\"left\">BSL sin35<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.37*<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.19<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.24<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">38.26*<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.16<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.75<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">0.3<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.89<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.18<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.24*<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">12.72*<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.71<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.75<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">0.6<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.54<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.18*<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.18*<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">9.25<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.36<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.75*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.29<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.21<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.25*<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">6.87<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.86<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.75*<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u043b\u044f sqrt \u0432\u0435\u0440\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b, \u0447\u0442\u043e BSL \u043b\u0443\u0447\u0448\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f sin35 \u043f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 thd \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f detour, \u0438 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f 30%. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 &#8212; v1 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 bsl \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438.<\/p>\n<h4>pilot v2<\/h4>\n<p>\u041f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u0442\u0430\u0439\u043b\u0430 \u0441\u0447\u0438\u0442\u0430\u0442\u044c &#8212; \u0434\u043e\u0440\u043e\u0433\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0431\u0440\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 256 (\u044d\u0442\u043e \u0447\u0442\u0435\u043d\u0438\u0435 6% \u0442\u0430\u0439\u043b\u0430, \u043d\u0430 pow &#8212; \u0448\u0443\u043c, \u043d\u043e \u043d\u0430 sqrt \u043e\u0449\u0443\u0442\u0438\u043c\u043e). \u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e:<\/p>\n<pre><code>    size_t density(float* dst, const size_t n, auto mask) {        std::array&lt;uint32x4_t, 4&gt; acc;        acc.fill(vdupq_n_u32(0));        for (size_t i = 0; i &lt; n; i += 16) {            for (size_t j = 0; j &lt; 4; ++j)                 acc[j] = vsubq_u32(acc[j], mask(vld1q_f32(dst + i + 4 * j)));        }        return vaddvq_u32(vaddq_u32(vaddq_u32(acc[0], acc[1]), vaddq_u32(acc[2], acc[3])));    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0440\u044e\u043a \u0437\u0434\u0435\u0441\u044c: true \u043b\u0435\u0439\u043d \u0431\u0438\u0442\u043c\u0430\u0441\u043a\u0438 &#8212; 0xFFFFFFFF = -1, \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u043b\u0435\u0439\u043d\u0430, \u043f\u043e \u0441\u0443\u0442\u0438, \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<p>Skip \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0440 \u0440\u0435\u0434\u043a\u043e \u043f\u0440\u043e\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u0435\u0441\u0442\u044c 80% \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 4 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u043f\u0443\u0441\u0442\u044b. \u041f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e <code>0.014<\/code> (<code>(1 - x)^16 = 0.8<\/code>)<\/p>\n<pre><code>    void pilot_v2(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        const float d_max = bsl_calibrate&lt;tile \/ 2&gt;(dst, 2 * tile, f, mask);        constexpr size_t probe = 256;        constexpr size_t xlo = 0.014 * probe;        const long long hi = d_max * probe;        dst += 2 * tile;        for (size_t i = 2 * tile; i &lt; n; i += tile) {            const long long cnt = density(dst, probe, mask);            if (cnt &gt; hi) {                if (cnt &lt; xlo)                    bsl&lt;true&gt;(dst, tile, f, mask);                else                    bsl&lt;false&gt;(dst, tile, f, mask);            } else if (cnt &lt; xlo)                detour&lt;true&gt;(dst, tile, w, f, mask);            else                detour&lt;false&gt;(dst, tile, w, f, mask);            dst += tile;        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0442\u0443\u0442 <code>hi<\/code> \u0438 <code>xlo<\/code> &#8212; \u043f\u043e\u0440\u043e\u0433\u0438 <code>d_max<\/code> \u0438 <code>0.014<\/code>, \u043d\u043e \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0434\u043b\u0438\u043d\u0443 \u043f\u0440\u043e\u0431\u044b(256).<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.1<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.2<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.3<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.4<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.5<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.6<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.7<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.8<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.9<\/p>\n<\/th>\n<th>\n<p align=\"left\">1<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v1 sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.25<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.72*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.48*<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.77*<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.41*<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.33*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.40<\/p>\n<\/td>\n<td>\n<p align=\"left\">8.62<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.93<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.36<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.91<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v2 sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">77.29*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.55<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.34<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.65<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.33<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.14<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.71<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.73<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.74<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.73<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.73<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.77<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.77<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.76<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.76<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.78*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.77*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.78*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.77*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.78*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v1 sin10<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.28<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.30*<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.18*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.18*<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.75*<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.73*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.94*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.31*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.36<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.02<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v2 sin10<\/p>\n<\/td>\n<td>\n<p align=\"left\">76.60*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.16<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.09<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.11<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.73<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.70<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.92<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.31*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.82<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.84<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL sin10<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.85*<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0440\u0438 thd = 0 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u043a\u0438\u043f\u0443 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0439 \u0432\u044b\u0438\u0433\u0440\u044b\u0448. \u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 thd \u0432\u0435\u0440\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f bsl. \u041d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430 \u043d\u0435\u043f\u043b\u043e\u0442\u043d\u044b\u0445 \u043c\u0430\u0441\u043a\u0430\u0445 \u0437\u0440\u044f \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f expand \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u044b\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432.<\/p>\n<h4>pilot v3<\/h4>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0432\u0435\u0440\u0441\u0438\u044e detour &#8212; \u0432\u043e \u0432\u0440\u0435\u043c\u044f compress \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u0443\u0441\u0442\u044b\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 (\u0432 \u0431\u0443\u0444\u0435\u0440 <code>idx<\/code>), \u0438 expand \u0431\u0443\u0434\u0435\u0442 \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u043d\u0438\u043c:<\/p>\n<pre><code>    template &lt;bool Skip&gt;    size_t detour_compact(float* dst, const size_t n, const auto w, auto f, auto mask) {        float* ptr = tmp.data();        size_t k = 0;        for (size_t i = 0; i &lt; n; i += 16) {            \/\/ \u043d\u0430\u0447\u0430\u043b\u043e \u0446\u0438\u043a\u043b\u0430 \u043a\u0430\u043a \u0432 detour                        if constexpr (Skip)                if (vmaxvq_u32(vaddq_u32(vaddq_u32(m[0], m[1]), vaddq_u32(m[2], m[3]))) == 0) continue;            std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) sk[j] = vaddvq_u32(vandq_u32(m[j], w));            for (size_t j = 0; j &lt; 4; ++j) {                s[k] = sk[j];                idx[k] = i + 4 * j;                k += bool(sk[j]);            }            \/\/ \u043a\u043e\u043d\u0435\u0446 \u0446\u0438\u043a\u043b\u0430 \u043a\u0430\u043a \u0432 detour        }        \/\/ \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u043a\u0430\u043a \u0432 detour                for (size_t j = 0; j &lt; 3; ++j) s[k + j] = 0, idx[k + j] = 0;        \/\/ 2 \u0444\u0430\u0437\u0430 \u043a\u0430\u043a \u0432 detour        k = (k + 3) &amp; ~size_t(3);        for (size_t i = 0; i &lt; k; i += 4) {            std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) sk[j] = s[i + j];            std::array&lt;float32x4_t, 4&gt; a;            for (size_t j = 0; j &lt; 4; ++j) a[j] = vld1q_f32(dst + idx[i + j]);            \/\/ \u0438 \u0437\u0434\u0435\u0441\u044c \u043a\u0430\u043a \u0432 detour            for (size_t j = 0; j &lt; 4; ++j)                vst1q_f32(dst + idx[i + j], vreinterpretq_f32_u8(vqtbl2q_u8(tbl[j], index[j])));            ptr += off[3] + (sk[3] &gt;&gt; 4);        }            return size;    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>k (\u043a\u043e\u043b-\u0432\u043e \u043d\u0435\u043f\u0443\u0441\u0442\u044b\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432) \u0434\u043e expand \u043e\u043a\u0440\u0443\u0433\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0440\u0445 \u0434\u043e \u043a\u0440\u0430\u0442\u043d\u043e\u0433\u043e 4, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435 \u0430\u043d\u0440\u043e\u043b\u043b\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0441\u0442\u0430\u0442\u043e\u043a.<\/p>\n<p>\u041d\u0435\u0442\u0443 \u0432\u0435\u0442\u043e\u043a \u0432 \u0433\u043e\u0440\u044f\u0447\u0438\u0445 \u0446\u0438\u043a\u043b\u0430\u0445 &#8212; \u043e\u043d\u0438 \u0431\u044b \u0443\u0431\u0438\u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 compress \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432. \u0412\u043c\u0435\u0441\u0442\u043e \u0432\u0435\u0442\u043e\u043a \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <code>bool(sk)<\/code>.<\/p>\n<p>\u042d\u0442\u0443 \u0432\u0435\u0440\u0441\u0438\u044e \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0442\u044f \u0431\u044b 50% \u0432\u0441\u0435\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 &#8212; \u043f\u0443\u0441\u0442\u044b\u0435. \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u0430\u044f \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c &#8212; 0.16 (<code>(1 - x) ^ 4 = 0.5<\/code>).<\/p>\n<pre><code>    void pilot_v3(float* dst, const size_t n, auto f, auto mask) {        \/\/ \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u0430\u043a \u0432 v2        constexpr size_t lo = 0.16 * probe;        for (size_t i = 2 * tile; i &lt; n; i += tile) {            const long long cnt = density(dst, probe, mask);            if (cnt &gt; hi) {                if (cnt &lt; xlo)                    bsl&lt;true&gt;(dst, tile, f, mask);                else                    bsl&lt;false&gt;(dst, tile, f, mask);            } else if (cnt &lt; xlo)                detour_compact&lt;true&gt;(dst, tile, w, f, mask);            else if (cnt &lt; lo)                detour_compact&lt;false&gt;(dst, tile, w, f, mask);            else                detour&lt;false&gt;(dst, tile, w, f, mask);            dst += tile;        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.02<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.04<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.06<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.08<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.1<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.12<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.14<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.16<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.18<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.2<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v2 sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">77.29*<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.67<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.40<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.70<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.18<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.66<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.15<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.68<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.24*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.82*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.43*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v3 sin35<\/p>\n<\/td>\n<td>\n<p align=\"left\">77.26<\/p>\n<\/td>\n<td>\n<p align=\"left\">23.71*<\/p>\n<\/td>\n<td>\n<p align=\"left\">22.19*<\/p>\n<\/td>\n<td>\n<p align=\"left\">20.48*<\/p>\n<\/td>\n<td>\n<p align=\"left\">19.03*<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.82*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.73*<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.76*<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.16<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.74<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.38<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v2 pow10<\/p>\n<\/td>\n<td>\n<p align=\"left\">72.88<\/p>\n<\/td>\n<td>\n<p align=\"left\">13.93<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.32<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.38<\/p>\n<\/td>\n<td>\n<p align=\"left\">8.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.97<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.18<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.54<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.02*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.59*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.24*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v3 pow10<\/p>\n<\/td>\n<td>\n<p align=\"left\">73.71*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.54*<\/p>\n<\/td>\n<td>\n<p align=\"left\">12.63*<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.07*<\/p>\n<\/td>\n<td>\n<p align=\"left\">8.39*<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.17*<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.26*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.55*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.02*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.59*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.24*<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 &#8212; \u043c\u044b \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u0441\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c v3 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0442\u0441\u044f:<\/p>\n<pre><code>for (size_t i = 0; i &lt; n; i++)    dst[i] = i % 4096 &gt;= 256;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c BSL, \u0445\u043e\u0442\u044c \u043d\u0430 3840 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0445 \u0442\u0430\u0439\u043b\u0430 \u043e\u043d \u043d\u0435 \u0432\u044b\u0433\u043e\u0434\u0435\u043d.<\/p>\n<h4>pilot v3.5<\/h4>\n<p>\u041f\u043e \u0441\u0430\u043c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 detour \u0432 \u0445\u0443\u0434\u0448\u0435\u043c \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c \u0432 3 \u0440\u0430\u0437\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 (\u043d\u0430 sqrt thd = 1), \u043d\u043e \u043d\u0430 pow, thd = 0, \u043e\u043d \u0432 37 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 BSL \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u0435\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e detour.<\/p>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442, \u0434\u043b\u044f bsl \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u0442\u044c\u0441\u044f &#8212; \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u043f\u043e tile \/ 8 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443\u043f\u0430\u043b\u0430 \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0438\u0436\u0435 <code>d_max<\/code> &#8212; \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 detour. \u0421\u0442\u043e\u0438\u0442\u044c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 1 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043d\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440. <code>acc = vsubq_u32(acc, m)<\/code>, \u043c\u0430\u0441\u043a\u0430 \u0432\u0435\u0434\u044c 0\/-1, \u0438 \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 probe, \u0442\u0443\u0442 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0447\u043d\u0430\u044f.<\/p>\n<pre><code>    size_t bsl_verified(float* dst, const size_t n, float d_max, auto f, auto mask) {        for (size_t i0 = 0; i0 &lt; 8; ++i0) {            std::array&lt;uint32x4_t, 4&gt; acc;            acc.fill(vdupq_n_u32(0));            for (size_t i = 0; i &lt; n \/ 8; i += 16) {                std::array&lt;float32x4_t, 4&gt; v;                for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(dst + 4 * j);                std::array&lt;uint32x4_t, 4&gt; m;                for (size_t j = 0; j &lt; 4; ++j) m[j] = mask(v[j]);                for (size_t j = 0; j &lt; 4; ++j) acc[j] = vsubq_u32(acc[j], m[j]);                for (size_t j = 0; j &lt; 4; ++j)                    vst1q_f32(dst + 4 * j, vbslq_f32(m[j], f(v[j]), v[j]));                                dst += 16;            }            const size_t cur = vaddvq_u32(vaddq_u32(vaddq_u32(acc[0], acc[1]), vaddq_u32(acc[2], acc[3])));            if (static_cast&lt;double&gt;(cur) \/ (n \/ 8) &lt; 0.75 * d_max) return (i0 + 1) * n \/ 8;        }        return n;    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 BSL \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043c\u0435\u043d\u044c\u0448\u0435 <code>0.75 * d_max<\/code>. \u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u043c\u0443 \u0443 \u043c\u0435\u043d\u044f \u043d\u0435\u0442, \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0431\u0440\u0430\u043d, \u043a\u0430\u043a \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043b\u0443\u0447\u0448\u0438\u0439.<\/p>\n<p>\u0418 \u0442\u043e\u0433\u0434\u0430 pilot v3.5 \u043d\u0430 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 &gt; hi \u0431\u0443\u0434\u0435\u0442 \u044e\u0437\u0430\u0442\u044c bsl_verified:<\/p>\n<pre><code>    void pilot_v3_5(float* dst, const size_t n, auto f, auto mask) {        \/\/ \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u0430\u043a \u0432 v3            for (size_t i = 2 * tile; i &lt; n; i += tile) {            const long long cnt = density(dst, probe, mask);            if (cnt &gt; hi) {                if (hi &lt; 0) {                    if (cnt &lt; xlo)                        bsl&lt;true&gt;(dst, tile, f, mask);                    else                        bsl&lt;false&gt;(dst, tile, f, mask);                } else {                    auto done = bsl_verified(dst, tile, d_max, f, mask);                    if (done &lt; tile)                        detour&lt;false&gt;(dst + done, tile - done, w, f, mask);                }            }            \/\/ \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0442\u043a\u0438 \u043a\u0430\u043a v3        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0438 \u0437\u0434\u0435\u0441\u044c \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0442\u0435\u0441\u0442:<\/p>\n<pre><code>for (size_t i = 0; i &lt; n; ++i)    dst[i] = i % 4096 &gt;= 390;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u043b\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0440\u043e\u0439\u0434\u0435\u0442 (\u0432 \u043d\u0435\u043c &gt; 75% \u043d\u0443\u043b\u0435\u0439), \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 &#8212; \u043d\u0435\u0442, \u043d\u0430 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u0440\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f bsl, \u0434\u043b\u044f pow \u044d\u0442\u043e \u0434\u043e\u0440\u043e\u0433\u043e. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 v3.5 &#8212; \u0443 \u043d\u0435\u0433\u043e \u043d\u0435\u0442\u0443 \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u043c\u0430\u0445\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u043c 256 \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h4>pilot v4<\/h4>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e v4 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442: bsl \u0441\u043e\u0440\u0432\u0430\u043b\u0441\u044f &#8212; \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u043c \u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 16 \u0442\u0430\u0439\u043b\u043e\u0432, \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0435 \u0431\u0435\u0440\u0435\u043c \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0442\u0430\u0439\u043b\u0430:<\/p>\n<pre><code>    void pilot_v4(float* dst, const size_t n, auto f, auto mask) {        \/\/ \u0442\u0443\u0442 \u043a\u0430\u043a \u0432 v3        size_t distrust = 0;        size_t prev = 0;        for (size_t i = 2 * tile; i &lt; n; i += tile) {            if (distrust) --distrust;            const long long cnt = distrust ? prev : density(dst, probe, mask);            if (cnt &gt; hi) {                if (hi &lt; 0) {                    if (cnt &lt; xlo) {                        bsl&lt;true&gt;(dst, tile, f, mask);                    } else {                        bsl&lt;false&gt;(dst, tile, f, mask);                    }                } else {                    if (distrust == 0) {                        auto done = bsl_verified(dst, tile, d_max, f, mask);                        if (done &lt; tile) {                            distrust = 16;                            const size_t rem = detour&lt;false&gt;(dst + done, tile - done, w, f, mask);                            prev = rem * probe \/ (tile - done);                        }                    } else {                        prev = detour&lt;false&gt;(dst, tile, w, f, mask) * probe \/ tile;                    }                }            } else if (cnt &lt; xlo) {                prev = detour_compact&lt;true&gt;(dst, tile, w, f, mask) * probe \/ tile;            } else if (cnt &lt; lo) {                prev = detour_compact&lt;false&gt;(dst, tile, w, f, mask) * probe \/ tile;            } else {                prev = detour&lt;false&gt;(dst, tile, w, f, mask) * probe \/ tile;            }            dst += tile;        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u0442 \u0442\u0435\u0441\u0442, pow10:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">1<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">tiled detour<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.18<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.94<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v3<\/p>\n<\/td>\n<td>\n<p align=\"left\">68.11<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.04<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v3.5<\/p>\n<\/td>\n<td>\n<p align=\"left\">68.67<\/p>\n<\/td>\n<td>\n<p align=\"left\">3.84<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v4<\/p>\n<\/td>\n<td>\n<p align=\"left\">69.51*<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.05*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.04<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.04<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>btw \u0442\u0443\u0442 thd \u0443\u0436\u0435 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c\u044e, \u043f\u0440\u0438 thd = 0 &#8212; \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c 0, \u043f\u0440\u0438 1 &#8212; 9.5%.<\/p>\n<p>\u0412\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u0443 v3.5 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043d\u0430 80%. \u0417\u0430\u043e\u0434\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0447\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 detour, \u0432\u0435\u0434\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f detour compact. \u042d\u0442\u043e \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430.<\/p>\n<h3>\u0418\u0442\u043e\u0433<\/h3>\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0442\u0438\u0432 BSL:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.05<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.1<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.2<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.3<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.4<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.5<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.6<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.7<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.8<\/p>\n<\/th>\n<th>\n<p align=\"left\">0.9<\/p>\n<\/th>\n<th>\n<p align=\"left\">1<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v4 sqrt<\/p>\n<\/td>\n<td>\n<p align=\"left\">69.81*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.99*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.73<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.83<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.07*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.98<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.96*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.96<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.91<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.77<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL sqrt<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.88<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.93<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.95*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.80*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.99<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.06*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.92<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.98*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.75<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.93*<\/p>\n<\/td>\n<td>\n<p align=\"left\">31.91*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v4 frfrexp<\/p>\n<\/td>\n<td>\n<p align=\"left\">69.41*<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.21*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.57<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.79<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.99<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.06<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.93<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.99<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.39<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.87<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.80<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL frfrexp<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.79<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.87<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.82*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.71*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.78*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.88*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.83*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.79*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.75*<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.75*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v4 sin10<\/p>\n<\/td>\n<td>\n<p align=\"left\">68.19*<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.82*<\/p>\n<\/td>\n<td>\n<p align=\"left\">14.84*<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.84*<\/p>\n<\/td>\n<td>\n<p align=\"left\">8.93*<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.55*<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.56*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.81*<\/p>\n<\/td>\n<td>\n<p align=\"left\">5.19*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.69<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.68<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.68<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL sin10<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.75<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.78<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.72<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.75<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.74<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.75<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.77<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.75<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.76*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.77*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.77*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot_v4 pow10<\/p>\n<\/td>\n<td>\n<p align=\"left\">64.17*<\/p>\n<\/td>\n<td>\n<p align=\"left\">10.76*<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.85*<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.04*<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.25*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.85*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.57*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.36*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.20*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.08*<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL pow10<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.01*<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0440\u043e\u0442\u0438\u0432 BSL \u043e\u043d \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u0432 \u0445\u0443\u0434\u0448\u0435\u043c \u043d\u0430 6%, \u043e\u0434\u043d\u0430\u043a\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0447\u0430\u0449\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442. \u0427\u0442\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0448, \u043c\u043e\u0436\u043d\u043e \u0434\u0438\u0441\u043f\u0430\u0442\u0447 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c &#8212; \u0432 density \u0438 bsl_verified \u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 4 \u0440\u0435\u0433\u0438\u0441\u0442\u0440. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u0430.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u043c\u0430\u0445 v4, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u0448\u0435\u043b &#8212; 512 \u043f\u043b\u043e\u0442\u043d\u044b\u0445, 512 \u043f\u0443\u0441\u0442\u044b\u0445, \u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435 \u043f\u043b\u043e\u0442\u043d\u043e\u0435 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0446\u0438\u043a\u043b\u0430.<\/p>\n<pre><code>const size_t cycle = 17 * 4096;for (size_t i = 0; i &lt; n; ++i) {    dst[i] = i % cycle &gt;= 512 &amp;&amp; i % cycle &lt; 1024;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u043f\u0440\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u0435\u0448\u0435\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0441 d_max &gt; 0 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435):<\/p>\n<pre><code>const auto a = vdupq_n_f32(0.5f);#pragma unrollfor (int i = 0; i &lt; 13; ++i) x = vfmaq_f32(a, x, a);return x;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">thd<\/p>\n<\/th>\n<th>\n<p align=\"left\">0<\/p>\n<\/th>\n<th>\n<p align=\"left\">1<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">tiled detour<\/p>\n<\/td>\n<td>\n<p align=\"left\">38.29<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.44<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v3<\/p>\n<\/td>\n<td>\n<p align=\"left\">74.72<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.81*<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v3.5<\/p>\n<\/td>\n<td>\n<p align=\"left\">74.84<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.04<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pilot v4<\/p>\n<\/td>\n<td>\n<p align=\"left\">74.89*<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.84<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">BSL<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.61<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.60<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>v3.5 \u0432 \u0445\u0443\u0434\u0448\u0435\u043c \u0443\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 BSL, \u0430 v4 \u0432 detour. \u0412\u044b\u0448\u0435 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043d\u043e, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 detour \u043c\u0435\u043d\u0435\u0435 \u0441\u0442\u0440\u0430\u0448\u0435\u043d. \u0422\u0430\u043a \u0447\u0442\u043e v4 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u0435\u0433\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u0435\u0448\u0435\u0432\u043b\u0435.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0443 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435\u0442\u0443 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0441 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0442\u0435\u0441\u0442.<\/p>\n<p>\u041a\u043e\u0434 \u0446\u0435\u043b\u0438\u043a\u043e\u043c: <a href=\"https:\/\/godbolt.org\/z\/nKhPjEn6v\" rel=\"noopener noreferrer nofollow\">godbolt<\/a>.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1063732\/\">https:\/\/habr.com\/ru\/articles\/1063732\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0417\u0430\u0434\u0430\u0447\u0430\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043a \u0442\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u043f\u043e\u0434 \u0443\u0441\u043b\u043e\u0432\u0438\u0435:for (size_t i = 0; i &lt; n; ++i)    if (mask(a[i])) a[i] = f(a[i]);\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:\u0412 \u0441\u0442\u0430\u0442\u044c\u0435:a[i] \u2208 (0, 1), thd \u2208 (0, 1), mask = a[i] &lt; thd; \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u044b (\u043a\u0440\u043e\u043c\u0435 \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0430\u0442\u044c\u0438)f \u0438\u0437 sqrt, frfrexp (\u043c\u0430\u043d\u0442\u0438\u0441\u0441\u0430 \u0447\u0438\u0441\u043b\u0430), sin 3.5 ULP, sin 1 ULP, pow 1 ULP (\u0438\u0437 SLEEF)\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b \u0432 \u043b\u044f\u043c\u0431\u0434\u0443 \u0441 always_inline, \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0437\u0430\u0438\u043d\u043b\u0430\u0439\u043d\u0438\u0442\u044c\u0441\u044f.\u0420\u0430\u0437\u043c\u0435\u0440 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 n \u043a\u0440\u0430\u0442\u0435\u043d \u0432\u0441\u0435\u043c \u0430\u043d\u0440\u043e\u043b\u043b\u0430\u043c, \u0442\u0430\u0439\u043b\u0430\u043c \u0438\u0442\u0434, \u0445\u0432\u043e\u0441\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u043e (BSL\/\u0441\u043a\u0430\u043b\u044f\u0440)\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 * &#8212; \u043b\u0443\u0447\u0448\u0438\u0439, \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f &#8212; GiB\/s\u0427\u0438\u0441\u043b\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u043d\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u0438\u0437-\u0437\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0435\u0431\u043b\u044e\u0442\u0441\u044f\u0412\u0441\u0435 \u0431\u0435\u043d\u0447\u0438: Apple M5; clang++ -O3 -std=c++23 -march=native; GiB\/s = (n * 4 bytes) \/ time, \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0438\u0437 720 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 (\u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u0432 \u043c\u0435\u043d\u044f\u044e\u0449\u0435\u043c\u0441\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e); n=1e7 + 2432BSL blend\u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u044c (\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043b\u0435\u0433\u043a\u0430\u044f \u0438\u043b\u0438 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0441\u043e\u043a\u0430\u044f), \u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d:    template &lt;bool Skip&gt;    void bsl(float* dst, const size_t n, auto f, auto mask) {        for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint32x4_t, 4&gt; m;            for (size_t j = 0; j &lt; 4; ++j) m[j] = mask(v[j]);            if constexpr (Skip) {                if (vmaxvq_u32(vaddq_u32(vaddq_u32(m[0], m[1]), vaddq_u32(m[2], m[3]))) == 0) continue;            }            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(dst + i + 4 * j, vbslq_f32(m[j], f(v[j]), v[j]));        }    }\u0421\u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043c\u0430\u0441\u043a\u0435. Skip &#8212; \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0436\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u0441\u043e\u043a \u043f\u043e\u043c\u043e\u0436\u0435\u0442, \u043d\u043e \u0438\u043d\u0430\u0447\u0435 \u043c\u0438\u0441\u043f\u0440\u0435\u0434\u0438\u043a\u0442\u044b \u0443\u0431\u044c\u044e\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0414\u0430\u043b\u044c\u0448\u0435 \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f.\u041e\u0434\u043d\u0430\u043a\u043e bsl \u043d\u0430 \u0442\u044f\u0436\u0435\u043b\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.Detour\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0435\u0435, \u0441\u043e\u0436\u043c\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 (compress), \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043d\u0438\u043c, \u0440\u0430\u0437\u043e\u0436\u043c\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e (expand).\u041d\u0430 avx512 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0432 \u043f\u0430\u0440\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043d\u043e \u043d\u0430 NEON &#8212; \u043d\u0435\u0442. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c.    constexpr double D = 0.845; \/\/ D \u0438 B \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u044b \u0431\u0443\u0434\u0443\u0442    constexpr double B = 0.3;    constexpr size_t tile = 4096;    constexpr std::array&lt;uint32_t, 4&gt; weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};    constexpr auto cps_tbl = compress_table();    constexpr auto exp_tbl = expand_table();    std::array&lt;float, tile + 16&gt; tmp;    std::array&lt;uint8_t, tile \/ 4 + 3&gt; s;    std::array&lt;uint16_t, tile \/ 4 + 3&gt; idx; \/\/ \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f    template &lt;bool Skip&gt;    size_t detour(float* dst, const size_t n, const auto w, auto f, auto mask) {        float* ptr = tmp.data();        for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint32x4_t, 4&gt; m;            for (size_t j = 0; j &lt; 4; ++j) m[j] = mask(v[j]);                        if constexpr (Skip)                if (vmaxvq_u32(vaddq_u32(vaddq_u32(m[0], m[1]), vaddq_u32(m[2], m[3]))) == 0) {                    s[i \/ 4] = s[i \/ 4 + 1] = s[i \/ 4 + 2] = s[i \/ 4 + 3] = 0;                    continue;                }                        std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) {                sk[j] = vaddvq_u32(vandq_u32(m[j], w));                s[i \/ 4 + j] = sk[j];            }            std::array&lt;size_t, 4&gt; off; off[0] = 0;            for (size_t j = 1; j &lt; 4; ++j) off[j] = off[j &#8212; 1] + (sk[j &#8212; 1] &gt;&gt; 4);             std::array&lt;uint8x16_t, 4&gt; index;            for (size_t j = 0; j &lt; 4; ++j) index[j] = vld1q_u8(cps_tbl[sk[j] &amp; 15].data());                        for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(ptr + off[j], vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(v[j]), index[j])));            ptr += off[3] + (sk[3] &gt;&gt; 4);        }        const size_t size = ptr &#8212; tmp.data();        if (size == 0) return size;                ptr = tmp.data();        for (size_t i = 0; i &lt; size; i += 16) {            std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(ptr + i + 4 * j);            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(ptr + i + 4 * j, f(v[j]));        }                for (size_t i = 0; i &lt; n; i += 16) {            std::array&lt;uint32_t, 4&gt; sk;            for (size_t j = 0; j &lt; 4; ++j) sk[j] = s[i \/ 4 + j];            std::array&lt;size_t, 4&gt; off{};            for (size_t j = 1; j &lt; 4; ++j) off[j] = off[j &#8212; 1] + (sk[j &#8212; 1] &gt;&gt; 4);             std::array&lt;float32x4_t, 4&gt; v;            for (size_t j = 0; j &lt; 4; ++j) v[j] = vld1q_f32(ptr + off[j]);            std::array&lt;float32x4_t, 4&gt; a;            for (size_t j = 0; j &lt; 4; ++j) a[j] = vld1q_f32(dst + i + 4 * j);            std::array&lt;uint8x16_t, 4&gt; index;            for (size_t j = 0; j &lt; 4; ++j) index[j] = vld1q_u8(exp_tbl[sk[j] &amp; 15].data());            std::array&lt;uint8x16x2_t, 4&gt; tbl;            for (size_t j = 0; j &lt; 4; ++j) tbl[j] = {{vreinterpretq_u8_f32(v[j]), vreinterpretq_u8_f32(a[j])}};            for (size_t j = 0; j &lt; 4; ++j) vst1q_f32(dst + i + 4 * j, vreinterpretq_f32_u8(vqtbl2q_u8(tbl[j], index[j])));            ptr += off[3] + (sk[3] &gt;&gt; 4);        }        return size;    }    void tiled_detour(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        for (size_t i = 0; i &lt; n; i += tile)            detour&lt;false&gt;(dst + i, tile, w, f, mask);    }compress \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u0442 \u0436\u0435 \u0447\u0442\u043e \u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.expand_table &#8212; \u0434\u043b\u044f true \u043b\u0435\u0439\u043d\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0436\u0430\u0442\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 (\u0431\u0430\u0439\u0442\u044b \u0438\u0437 [0, 15]), \u0430 \u0434\u043b\u044f false &#8212; \u0442\u0435 \u0436\u0435 \u0431\u0430\u0439\u0442\u044b + 16. \u041f\u043e\u0442\u043e\u043c tbl2 \u043f\u043e {\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435, \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435}, \u0432 \u043e\u0431\u0449\u0435\u043c \u0442\u043e\u0442 \u0436\u0435 \u0442\u0440\u044e\u043a, \u0447\u0442\u043e \u0438 \u0432 compress\u0418 \u0435\u0449\u0435:\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0441\u043a\u0438\u043f\u0430\u0435\u0442\u0441\u044f expand \u043d\u0430 \u043f\u0443\u0441\u0442\u044b\u0445 \u0442\u0430\u0439\u043b\u0430\u0445.\u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0430\u0439\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0435\u0448\u042d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 tile=4096 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d.s \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c addv\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c BSL \u043e\u0442 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442. sqrt 32.1, sin35 &#8212; 9.7, pow10 1.02.thd00.10.20.30.40.50.60.70.80.91detour sqrt38.03*18.8117.7816.8215.9815.2114.5113.8513.2412.7112.30detour sin3538.16*16.70*14.46*12.71*11.36*10.25*9.358.597.957.396.95detour pow1038.09*6.83*4.13*2.96*2.31*1.89*1.60*1.39*1.22*1.10*0.99\u0414\u043b\u044f \u0434\u0435\u0448\u0435\u0432\u043e\u0433\u043e sqrt \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0433\u043e\u0434\u0435\u043d BSL (\u043a\u0440\u043e\u043c\u0435 thd = 0, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e), \u0430 \u0434\u043b\u044f \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0440\u043e\u0433\u043e\u0433\u043e pow &#8212; detour (\u0435\u0441\u043b\u0438 thd != 1, \u043a\u043e\u043d\u0435\u0447\u043d\u043e)\u041a\u043e\u0433\u0434\u0430 \u043e\u043a\u0443\u043f\u0430\u0435\u0442\u0441\u044f detour\u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043c:B &#8212; \u043e\u0432\u0435\u0440\u0445\u0435\u0434 BSL(vld + vbsl + vst) \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440.D &#8212; \u043e\u0432\u0435\u0440\u0445\u0435\u0434 detour(\u0441\u0436\u0430\u0442\u0438\u0435 + \u0440\u0430\u0437\u0436\u0430\u0442\u0438\u0435) \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440.T &#8212; \u0446\u0435\u043d\u0430 f \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440 (\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0446\u0435\u043d\u0443 f &gt;&gt; \u0446\u0435\u043d\u044b mask, \u0432\u043b\u0438\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u043b\u0438\u0431\u0440\u043e\u0432\u043a\u0438).d &#8212; \u0434\u043e\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f.BSL \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 f \u043a\u043e \u0432\u0441\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043c, \u0430 detour \u0442\u043e\u043b\u044c\u043a\u043e \u043a d &#8212; \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 T * (1 &#8212; d). \u0417\u043d\u0430\u0447\u0438\u0442 detour \u0432\u044b\u0433\u043e\u0434\u0435\u043d \u043a\u043e\u0433\u0434\u0430 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u0435\u0442 D &#8212; B:T * (1 &#8212; d) &gt; D &#8212; Bdetour \u0432\u044b\u0433\u043e\u0434\u0435\u043d \u043a\u043e\u0433\u0434\u0430 d \u043c\u0435\u043d\u044c\u0448\u0435 d_max = 1 &#8212; (D &#8212; B) \/ T.B \u0438 D &#8212; \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442 \u0436\u0435\u043b\u0435\u0437\u0430, \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b, \u043f\u043e\u043c\u0435\u0440\u0438\u043c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 (\u0443 \u043c\u0435\u043d\u044f &#8212; B = 0.3, D = 0.845 ns\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440) T &#8212; \u0443\u0437\u043d\u0430\u0435\u043c \u0437\u0430 \u043f\u0435\u0440\u0432\u044b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u0439\u043b\u043e\u0432, \u043c\u0435\u0440\u044f\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b BSL. \u0410 \u043f\u043e \u043d\u0435\u043c\u0443 \u0443\u0437\u043d\u0430\u0435\u043c \u0438 d_max:    template&lt;size_t tile&gt;    double bsl_calibrate(float* dst, const size_t len, auto f, auto mask) {        double ns = 1e18;        for (size_t i = 0; i &lt; len; i += tile) {            const auto st = std::chrono::high_resolution_clock::now();            bsl&lt;false&gt;(dst, tile, f, mask);            const auto ed = std::chrono::high_resolution_clock::now();            ns = std::min(ns, std::chrono::duration&lt;double, std::nano&gt;(ed &#8212; st).count());            dst += tile;        }        const double t = std::max(1e-9, ns \/ (tile \/ 4.0) &#8212; B);        return 1.0 &#8212; (D &#8212; B) \/ t;    }\u0417\u0434\u0435\u0441\u044c:\u044d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 4 \u0442\u0430\u0439\u043b\u0430 \u043f\u043e 2048 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.min \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432 \u043a \u0448\u0443\u043c\u0443 \u0447\u0435\u043c \u0441\u0440\u0435\u0434\u043d\u0435\u0435.\u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0430\u043b\u0438\u0431\u0440\u043e\u0432\u043a\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u0439\u043b\u043e\u0432.\u043c\u0435\u0440\u044f\u0435\u043c bsl, \u0432\u0435\u0434\u044c \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 f, \u0442\u0430\u043a \u0447\u0442\u043e T = t_bsl &#8212; B.std::max \u0442\u0443\u0442 \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u043e\u0442 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 0 \u0438 \u043e\u0442 t &lt; 0 \u043f\u0440\u0438 \u043e\u0447\u0435\u043d\u044c \u0434\u0435\u0448\u0435\u0432\u043e\u043c T.pilot v1bsl \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435, \u043a\u043e\u0433\u0434\u0430 d_max &lt; 0:    void pilot_v1(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        const float d_max = bsl_calibrate&lt;tile \/ 2&gt;(dst, 2 * tile, f, mask);        dst += 2 * tile;        for (size_t i = 2 * tile; i &lt; n; i += tile) {            if (d_max &lt; 0)                bsl&lt;false&gt;(dst, tile, f, mask);            else                detour&lt;false&gt;(dst, tile, w, f, mask);            dst += tile;        }    }thdtiled detour sqrtpilot v1 sqrtBSL sqrttiled detour sin35pilot v1 sin35BSL sin35038.37*32.1932.2438.26*38.169.750.316.8932.1832.24*12.72*12.719.750.614.5432.18*32.18*9.259.369.75*112.2932.2132.25*6.876.869.75*\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u043b\u044f sqrt \u0432\u0435\u0440\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b, \u0447\u0442\u043e BSL \u043b\u0443\u0447\u0448\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f sin35 \u043f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 thd \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f detour, \u0438 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f 30%. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 &#8212; v1 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 bsl \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u0435\u043d \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438.pilot v2\u041f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u0442\u0430\u0439\u043b\u0430 \u0441\u0447\u0438\u0442\u0430\u0442\u044c &#8212; \u0434\u043e\u0440\u043e\u0433\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0431\u0440\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 256 (\u044d\u0442\u043e \u0447\u0442\u0435\u043d\u0438\u0435 6% \u0442\u0430\u0439\u043b\u0430, \u043d\u0430 pow &#8212; \u0448\u0443\u043c, \u043d\u043e \u043d\u0430 sqrt \u043e\u0449\u0443\u0442\u0438\u043c\u043e). \u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e:    size_t density(float* dst, const size_t n, auto mask) {        std::array&lt;uint32x4_t, 4&gt; acc;        acc.fill(vdupq_n_u32(0));        for (size_t i = 0; i &lt; n; i += 16) {            for (size_t j = 0; j &lt; 4; ++j)                 acc[j] = vsubq_u32(acc[j], mask(vld1q_f32(dst + i + 4 * j)));        }        return vaddvq_u32(vaddq_u32(vaddq_u32(acc[0], acc[1]), vaddq_u32(acc[2], acc[3])));    }\u0422\u0440\u044e\u043a \u0437\u0434\u0435\u0441\u044c: true \u043b\u0435\u0439\u043d \u0431\u0438\u0442\u043c\u0430\u0441\u043a\u0438 &#8212; 0xFFFFFFFF = -1, \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u043b\u0435\u0439\u043d\u0430, \u043f\u043e \u0441\u0443\u0442\u0438, \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435.Skip \u0432\u044b\u0433\u043e\u0434\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0440 \u0440\u0435\u0434\u043a\u043e \u043f\u0440\u043e\u043c\u0430\u0445\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u0435\u0441\u0442\u044c 80% \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 4 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u043f\u0443\u0441\u0442\u044b. \u041f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 0.014 ((1 &#8212; x)^16 = 0.8)    void pilot_v2(float* dst, const size_t n, auto f, auto mask) {        const auto w = vld1q_u32(weights.data());        const float d_max = &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-488795","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/488795","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=488795"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/488795\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=488795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=488795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=488795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}