LCOV - code coverage report
Current view: top level - lib/acl - acl_run_avx512x16.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 39 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 2 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 12 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2020 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : /*
       6                 :            :  * Defines required by "acl_run_avx512_common.h".
       7                 :            :  * Note that all of them has to be undefined by the end
       8                 :            :  * of this file, as "acl_run_avx512_common.h" can be included several
       9                 :            :  * times from different *.h files for the same *.c.
      10                 :            :  */
      11                 :            : 
      12                 :            : /*
      13                 :            :  * This implementation uses 512-bit registers(zmm) and intrinsics.
      14                 :            :  * So our main SIMD type is 512-bit width and each such variable can
      15                 :            :  * process sizeof(__m512i) / sizeof(uint32_t) == 16 entries in parallel.
      16                 :            :  */
      17                 :            : #define _T_simd         __m512i
      18                 :            : #define _T_mask         __mmask16
      19                 :            : 
      20                 :            : /* Naming convention for static const variables. */
      21                 :            : #define _SC_(x)         zmm_##x
      22                 :            : #define _SV_(x)         (zmm_##x.z)
      23                 :            : 
      24                 :            : /* Naming convention for internal functions. */
      25                 :            : #define _F_(x)          x##_avx512x16
      26                 :            : 
      27                 :            : /*
      28                 :            :  * Same intrinsics have different syntaxes (depending on the bit-width),
      29                 :            :  * so to overcome that few macros need to be defined.
      30                 :            :  */
      31                 :            : 
      32                 :            : /* Naming convention for generic epi(packed integers) type intrinsics. */
      33                 :            : #define _M_I_(x)        _mm512_##x
      34                 :            : 
      35                 :            : /* Naming convention for si(whole simd integer) type intrinsics. */
      36                 :            : #define _M_SI_(x)       _mm512_##x##_si512
      37                 :            : 
      38                 :            : /* Naming convention for masked gather type intrinsics. */
      39                 :            : #define _M_MGI_(x)      _mm512_##x
      40                 :            : 
      41                 :            : /* Naming convention for gather type intrinsics. */
      42                 :            : #define _M_GI_(name, idx, base, scale)  _mm512_##name(idx, base, scale)
      43                 :            : 
      44                 :            : /* num/mask of transitions per SIMD regs */
      45                 :            : #define _SIMD_MASK_BIT_ (sizeof(_T_simd) / sizeof(uint32_t))
      46                 :            : #define _SIMD_MASK_MAX_ RTE_LEN2MASK(_SIMD_MASK_BIT_, uint32_t)
      47                 :            : 
      48                 :            : #define _SIMD_FLOW_NUM_ (2 * _SIMD_MASK_BIT_)
      49                 :            : #define _SIMD_FLOW_MSK_ (_SIMD_FLOW_NUM_ - 1)
      50                 :            : 
      51                 :            : /* num/mask of pointers per SIMD regs */
      52                 :            : #define _SIMD_PTR_NUM_  (sizeof(_T_simd) / sizeof(uintptr_t))
      53                 :            : #define _SIMD_PTR_MSK_  RTE_LEN2MASK(_SIMD_PTR_NUM_, uint32_t)
      54                 :            : 
      55                 :            : static const __rte_x86_zmm_t _SC_(match_mask) = {
      56                 :            :         .u32 = {
      57                 :            :                 RTE_ACL_NODE_MATCH,
      58                 :            :                 RTE_ACL_NODE_MATCH,
      59                 :            :                 RTE_ACL_NODE_MATCH,
      60                 :            :                 RTE_ACL_NODE_MATCH,
      61                 :            :                 RTE_ACL_NODE_MATCH,
      62                 :            :                 RTE_ACL_NODE_MATCH,
      63                 :            :                 RTE_ACL_NODE_MATCH,
      64                 :            :                 RTE_ACL_NODE_MATCH,
      65                 :            :                 RTE_ACL_NODE_MATCH,
      66                 :            :                 RTE_ACL_NODE_MATCH,
      67                 :            :                 RTE_ACL_NODE_MATCH,
      68                 :            :                 RTE_ACL_NODE_MATCH,
      69                 :            :                 RTE_ACL_NODE_MATCH,
      70                 :            :                 RTE_ACL_NODE_MATCH,
      71                 :            :                 RTE_ACL_NODE_MATCH,
      72                 :            :                 RTE_ACL_NODE_MATCH,
      73                 :            :         },
      74                 :            : };
      75                 :            : 
      76                 :            : static const __rte_x86_zmm_t _SC_(index_mask) = {
      77                 :            :         .u32 = {
      78                 :            :                 RTE_ACL_NODE_INDEX,
      79                 :            :                 RTE_ACL_NODE_INDEX,
      80                 :            :                 RTE_ACL_NODE_INDEX,
      81                 :            :                 RTE_ACL_NODE_INDEX,
      82                 :            :                 RTE_ACL_NODE_INDEX,
      83                 :            :                 RTE_ACL_NODE_INDEX,
      84                 :            :                 RTE_ACL_NODE_INDEX,
      85                 :            :                 RTE_ACL_NODE_INDEX,
      86                 :            :                 RTE_ACL_NODE_INDEX,
      87                 :            :                 RTE_ACL_NODE_INDEX,
      88                 :            :                 RTE_ACL_NODE_INDEX,
      89                 :            :                 RTE_ACL_NODE_INDEX,
      90                 :            :                 RTE_ACL_NODE_INDEX,
      91                 :            :                 RTE_ACL_NODE_INDEX,
      92                 :            :                 RTE_ACL_NODE_INDEX,
      93                 :            :                 RTE_ACL_NODE_INDEX,
      94                 :            :         },
      95                 :            : };
      96                 :            : 
      97                 :            : static const __rte_x86_zmm_t _SC_(trlo_idle) = {
      98                 :            :         .u32 = {
      99                 :            :                 RTE_ACL_IDLE_NODE,
     100                 :            :                 RTE_ACL_IDLE_NODE,
     101                 :            :                 RTE_ACL_IDLE_NODE,
     102                 :            :                 RTE_ACL_IDLE_NODE,
     103                 :            :                 RTE_ACL_IDLE_NODE,
     104                 :            :                 RTE_ACL_IDLE_NODE,
     105                 :            :                 RTE_ACL_IDLE_NODE,
     106                 :            :                 RTE_ACL_IDLE_NODE,
     107                 :            :                 RTE_ACL_IDLE_NODE,
     108                 :            :                 RTE_ACL_IDLE_NODE,
     109                 :            :                 RTE_ACL_IDLE_NODE,
     110                 :            :                 RTE_ACL_IDLE_NODE,
     111                 :            :                 RTE_ACL_IDLE_NODE,
     112                 :            :                 RTE_ACL_IDLE_NODE,
     113                 :            :                 RTE_ACL_IDLE_NODE,
     114                 :            :                 RTE_ACL_IDLE_NODE,
     115                 :            :         },
     116                 :            : };
     117                 :            : 
     118                 :            : static const __rte_x86_zmm_t _SC_(trhi_idle) = {
     119                 :            :         .u32 = {
     120                 :            :                 0, 0, 0, 0,
     121                 :            :                 0, 0, 0, 0,
     122                 :            :                 0, 0, 0, 0,
     123                 :            :                 0, 0, 0, 0,
     124                 :            :         },
     125                 :            : };
     126                 :            : 
     127                 :            : static const __rte_x86_zmm_t _SC_(shuffle_input) = {
     128                 :            :         .u32 = {
     129                 :            :                 0x00000000, 0x04040404, 0x08080808, 0x0c0c0c0c,
     130                 :            :                 0x00000000, 0x04040404, 0x08080808, 0x0c0c0c0c,
     131                 :            :                 0x00000000, 0x04040404, 0x08080808, 0x0c0c0c0c,
     132                 :            :                 0x00000000, 0x04040404, 0x08080808, 0x0c0c0c0c,
     133                 :            :         },
     134                 :            : };
     135                 :            : 
     136                 :            : static const __rte_x86_zmm_t _SC_(four_32) = {
     137                 :            :         .u32 = {
     138                 :            :                 4, 4, 4, 4,
     139                 :            :                 4, 4, 4, 4,
     140                 :            :                 4, 4, 4, 4,
     141                 :            :                 4, 4, 4, 4,
     142                 :            :         },
     143                 :            : };
     144                 :            : 
     145                 :            : static const __rte_x86_zmm_t _SC_(idx_add) = {
     146                 :            :         .u32 = {
     147                 :            :                 0, 1, 2, 3,
     148                 :            :                 4, 5, 6, 7,
     149                 :            :                 8, 9, 10, 11,
     150                 :            :                 12, 13, 14, 15,
     151                 :            :         },
     152                 :            : };
     153                 :            : 
     154                 :            : static const __rte_x86_zmm_t _SC_(range_base) = {
     155                 :            :         .u32 = {
     156                 :            :                 0xffffff00, 0xffffff04, 0xffffff08, 0xffffff0c,
     157                 :            :                 0xffffff00, 0xffffff04, 0xffffff08, 0xffffff0c,
     158                 :            :                 0xffffff00, 0xffffff04, 0xffffff08, 0xffffff0c,
     159                 :            :                 0xffffff00, 0xffffff04, 0xffffff08, 0xffffff0c,
     160                 :            :         },
     161                 :            : };
     162                 :            : 
     163                 :            : static const __rte_x86_zmm_t _SC_(pminp) = {
     164                 :            :         .u32 = {
     165                 :            :                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     166                 :            :                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     167                 :            :         },
     168                 :            : };
     169                 :            : 
     170                 :            : static const _T_mask _SC_(pmidx_msk) = 0x5555;
     171                 :            : 
     172                 :            : static const __rte_x86_zmm_t _SC_(pmidx[2]) = {
     173                 :            :         [0] = {
     174                 :            :                 .u32 = {
     175                 :            :                         0, 0, 1, 0, 2, 0, 3, 0,
     176                 :            :                         4, 0, 5, 0, 6, 0, 7, 0,
     177                 :            :                 },
     178                 :            :         },
     179                 :            :         [1] = {
     180                 :            :                 .u32 = {
     181                 :            :                         8, 0, 9, 0, 10, 0, 11, 0,
     182                 :            :                         12, 0, 13, 0, 14, 0, 15, 0,
     183                 :            :                 },
     184                 :            :         },
     185                 :            : };
     186                 :            : 
     187                 :            : /*
     188                 :            :  * unfortunately current AVX512 ISA doesn't provide ability for
     189                 :            :  * gather load on a byte quantity. So we have to mimic it in SW,
     190                 :            :  * by doing 8x1B scalar loads.
     191                 :            :  */
     192                 :            : static inline __m256i
     193                 :            : _m512_mask_gather_epi8x8(__m512i pdata, __mmask8 mask)
     194                 :            : {
     195                 :            :         rte_ymm_t v;
     196                 :            :         __rte_x86_zmm_t p;
     197                 :            : 
     198                 :            :         static const uint32_t zero;
     199                 :            : 
     200                 :          0 :         p.z = _mm512_mask_set1_epi64(pdata, mask ^ _SIMD_PTR_MSK_,
     201                 :            :                 (uintptr_t)&zero);
     202                 :            : 
     203                 :          0 :         v.u32[0] = *(uint8_t *)p.u64[0];
     204                 :          0 :         v.u32[1] = *(uint8_t *)p.u64[1];
     205                 :          0 :         v.u32[2] = *(uint8_t *)p.u64[2];
     206                 :          0 :         v.u32[3] = *(uint8_t *)p.u64[3];
     207                 :          0 :         v.u32[4] = *(uint8_t *)p.u64[4];
     208                 :          0 :         v.u32[5] = *(uint8_t *)p.u64[5];
     209                 :          0 :         v.u32[6] = *(uint8_t *)p.u64[6];
     210                 :          0 :         v.u32[7] = *(uint8_t *)p.u64[7];
     211                 :            : 
     212                 :          0 :         return v.y;
     213                 :            : }
     214                 :            : 
     215                 :            : /*
     216                 :            :  * Gather 4/1 input bytes for up to 16 (2*8) locations in parallel.
     217                 :            :  */
     218                 :            : static __rte_always_inline __m512i
     219                 :            : _F_(gather_bytes)(__m512i zero, const __m512i p[2], const uint32_t m[2],
     220                 :            :         uint32_t bnum)
     221                 :            : {
     222                 :            :         __m256i inp[2];
     223                 :            : 
     224         [ #  # ]:          0 :         if (bnum == sizeof(uint8_t)) {
     225                 :            :                 inp[0] = _m512_mask_gather_epi8x8(p[0], m[0]);
     226                 :            :                 inp[1] = _m512_mask_gather_epi8x8(p[1], m[1]);
     227                 :            :         } else {
     228                 :            :                 inp[0] = _mm512_mask_i64gather_epi32(
     229                 :            :                                 _mm512_castsi512_si256(zero),
     230                 :            :                                 m[0], p[0], NULL, sizeof(uint8_t));
     231                 :            :                 inp[1] = _mm512_mask_i64gather_epi32(
     232                 :            :                                 _mm512_castsi512_si256(zero),
     233                 :            :                                 m[1], p[1], NULL, sizeof(uint8_t));
     234                 :            :         }
     235                 :            : 
     236                 :            :         /* squeeze input into one 512-bit register */
     237                 :            :         return _mm512_permutex2var_epi32(_mm512_castsi256_si512(inp[0]),
     238                 :            :                         _SV_(pminp), _mm512_castsi256_si512(inp[1]));
     239                 :            : }
     240                 :            : 
     241                 :            : /*
     242                 :            :  * Resolve matches for multiple categories (GT 8, use 512b instructions/regs)
     243                 :            :  */
     244                 :            : static inline void
     245                 :          0 : resolve_mcgt8_avx512x1(uint32_t result[],
     246                 :            :         const struct rte_acl_match_results pr[], const uint32_t match[],
     247                 :            :         uint32_t nb_pkt, uint32_t nb_cat, uint32_t nb_trie)
     248                 :            : {
     249                 :            :         const int32_t *pri;
     250                 :            :         const uint32_t *pm, *res;
     251                 :            :         uint32_t i, k, mi;
     252                 :            :         __mmask16 cm, sm;
     253                 :            :         __m512i cp, cr, np, nr;
     254                 :            : 
     255                 :          0 :         res = pr->results;
     256                 :          0 :         pri = pr->priority;
     257                 :            : 
     258                 :          0 :         cm = (1 << nb_cat) - 1;
     259                 :            : 
     260         [ #  # ]:          0 :         for (k = 0; k != nb_pkt; k++, result += nb_cat) {
     261                 :            : 
     262                 :          0 :                 mi = match[k] << ACL_MATCH_LOG;
     263                 :            : 
     264                 :          0 :                 cr = _mm512_maskz_loadu_epi32(cm, res + mi);
     265                 :          0 :                 cp = _mm512_maskz_loadu_epi32(cm, pri + mi);
     266                 :            : 
     267         [ #  # ]:          0 :                 for (i = 1, pm = match + nb_pkt; i != nb_trie;
     268                 :          0 :                                 i++, pm += nb_pkt) {
     269                 :            : 
     270                 :          0 :                         mi = pm[k] << ACL_MATCH_LOG;
     271                 :            : 
     272                 :          0 :                         nr = _mm512_maskz_loadu_epi32(cm, res + mi);
     273                 :          0 :                         np = _mm512_maskz_loadu_epi32(cm, pri + mi);
     274                 :            : 
     275                 :            :                         sm = _mm512_cmpgt_epi32_mask(cp, np);
     276                 :          0 :                         cr = _mm512_mask_mov_epi32(nr, sm, cr);
     277                 :            :                         cp = _mm512_mask_mov_epi32(np, sm, cp);
     278                 :            :                 }
     279                 :            : 
     280                 :            :                 _mm512_mask_storeu_epi32(result, cm, cr);
     281                 :            :         }
     282                 :          0 : }
     283                 :            : 
     284                 :            : #include "acl_run_avx512_common.h"
     285                 :            : 
     286                 :            : /*
     287                 :            :  * Perform search for up to (2 * 16) flows in parallel.
     288                 :            :  * Use two sets of metadata, each serves 16 flows max.
     289                 :            :  */
     290                 :            : static inline int
     291                 :          0 : search_avx512x16x2(const struct rte_acl_ctx *ctx, const uint8_t **data,
     292                 :            :         uint32_t *results, uint32_t total_packets, uint32_t categories)
     293                 :          0 : {
     294                 :            :         uint32_t i, *pm;
     295                 :            :         const struct rte_acl_match_results *pr;
     296                 :            :         struct acl_flow_avx512 flow;
     297                 :          0 :         uint32_t match[ctx->num_tries * total_packets];
     298                 :            : 
     299         [ #  # ]:          0 :         for (i = 0, pm = match; i != ctx->num_tries; i++, pm += total_packets) {
     300                 :            : 
     301                 :            :                 /* setup for next trie */
     302                 :            :                 acl_set_flow_avx512(&flow, ctx, i, data, pm, total_packets);
     303                 :            : 
     304                 :            :                 /* process the trie */
     305                 :          0 :                 _F_(search_trie)(&flow);
     306                 :            :         }
     307                 :            : 
     308                 :            :         /* resolve matches */
     309                 :          0 :         pr = (const struct rte_acl_match_results *)
     310                 :          0 :                 (ctx->trans_table + ctx->match_index);
     311                 :            : 
     312         [ #  # ]:          0 :         if (categories == 1)
     313                 :          0 :                 _F_(resolve_single_cat)(results, pr, match, total_packets,
     314                 :            :                         ctx->num_tries);
     315         [ #  # ]:          0 :         else if (categories <= RTE_ACL_MAX_CATEGORIES / 2)
     316                 :          0 :                 resolve_mcle8_avx512x1(results, pr, match, total_packets,
     317                 :            :                         categories, ctx->num_tries);
     318                 :            :         else
     319                 :          0 :                 resolve_mcgt8_avx512x1(results, pr, match, total_packets,
     320                 :            :                         categories, ctx->num_tries);
     321                 :            : 
     322                 :          0 :         return 0;
     323                 :            : }
     324                 :            : 
     325                 :            : #undef _SIMD_PTR_MSK_
     326                 :            : #undef _SIMD_PTR_NUM_
     327                 :            : #undef _SIMD_FLOW_MSK_
     328                 :            : #undef _SIMD_FLOW_NUM_
     329                 :            : #undef _SIMD_MASK_MAX_
     330                 :            : #undef _SIMD_MASK_BIT_
     331                 :            : #undef _M_GI_
     332                 :            : #undef _M_MGI_
     333                 :            : #undef _M_SI_
     334                 :            : #undef _M_I_
     335                 :            : #undef _F_
     336                 :            : #undef _SV_
     337                 :            : #undef _SC_
     338                 :            : #undef _T_mask
     339                 :            : #undef _T_simd

Generated by: LCOV version 1.14