LCOV - code coverage report
Current view: top level - vppinfra/vector - compress.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 20 54 37.0 %
Date: 2023-10-26 01:39:38 Functions: 2 4 50.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright(c) 2021 Cisco Systems, Inc.
       3             :  */
       4             : 
       5             : #ifndef included_vector_compress_h
       6             : #define included_vector_compress_h
       7             : #include <vppinfra/clib.h>
       8             : #include <vppinfra/memcpy.h>
       9             : 
      10             : static_always_inline u64 *
      11           0 : clib_compress_u64_x64 (u64 *dst, u64 *src, u64 mask)
      12             : {
      13             : #if defined(CLIB_HAVE_VEC512_COMPRESS)
      14           0 :   u64x8u *sv = (u64x8u *) src;
      15           0 :   for (int i = 0; i < 8; i++)
      16             :     {
      17           0 :       u64x8_compress_store (sv[i], mask, dst);
      18           0 :       dst += _popcnt32 ((u8) mask);
      19           0 :       mask >>= 8;
      20             :     }
      21             : #elif defined(CLIB_HAVE_VEC256_COMPRESS)
      22           0 :   u64x4u *sv = (u64x4u *) src;
      23           0 :   for (int i = 0; i < 16; i++)
      24             :     {
      25           0 :       u64x4_compress_store (sv[i], mask, dst);
      26           0 :       dst += _popcnt32 (((u8) mask) & 0x0f);
      27           0 :       mask >>= 4;
      28             :     }
      29             : #else
      30             :   u32 i;
      31           0 :   foreach_set_bit_index (i, mask)
      32           0 :     dst++[0] = src[i];
      33             : #endif
      34           0 :   return dst;
      35             : }
      36             : 
      37             : /** \brief Compress array of 64-bit elemments into destination array based on
      38             :  * mask
      39             : 
      40             :     @param dst destination array of u64 elements
      41             :     @param src source array of u64 elements
      42             :     @param mask array of u64 values representing compress mask
      43             :     @param n_elts number of elements in the source array
      44             :     @return number of elements stored in destionation array
      45             : */
      46             : 
      47             : static_always_inline u32
      48           0 : clib_compress_u64 (u64 *dst, u64 *src, u64 *mask, u32 n_elts)
      49             : {
      50           0 :   u64 *dst0 = dst;
      51           0 :   while (n_elts >= 64)
      52             :     {
      53           0 :       if (mask[0] == ~0ULL)
      54             :         {
      55           0 :           clib_memcpy_fast (dst, src, 64 * sizeof (u64));
      56           0 :           dst += 64;
      57             :         }
      58             :       else
      59           0 :         dst = clib_compress_u64_x64 (dst, src, mask[0]);
      60             : 
      61           0 :       mask++;
      62           0 :       src += 64;
      63           0 :       n_elts -= 64;
      64             :     }
      65             : 
      66           0 :   if (PREDICT_TRUE (n_elts == 0))
      67           0 :     return dst - dst0;
      68             : 
      69           0 :   return clib_compress_u64_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
      70             : }
      71             : 
      72             : static_always_inline u32 *
      73     8448590 : clib_compress_u32_x64 (u32 *dst, u32 *src, u64 mask)
      74             : {
      75             : #if defined(CLIB_HAVE_VEC512_COMPRESS)
      76           0 :   u32x16u *sv = (u32x16u *) src;
      77           0 :   for (int i = 0; i < 4; i++)
      78             :     {
      79           0 :       u32x16_compress_store (sv[i], mask, dst);
      80           0 :       dst += _popcnt32 ((u16) mask);
      81           0 :       mask >>= 16;
      82             :     }
      83             : 
      84             : #elif defined(CLIB_HAVE_VEC256_COMPRESS)
      85     8448590 :   u32x8u *sv = (u32x8u *) src;
      86    76037290 :   for (int i = 0; i < 8; i++)
      87             :     {
      88    67588680 :       u32x8_compress_store (sv[i], mask, dst);
      89    67588680 :       dst += _popcnt32 ((u8) mask);
      90    67588680 :       mask >>= 8;
      91             :     }
      92             : #else
      93             :   u32 i;
      94           0 :   foreach_set_bit_index (i, mask)
      95           0 :     dst++[0] = src[i];
      96             : #endif
      97     8448590 :   return dst;
      98             : }
      99             : 
     100             : /** \brief Compress array of 32-bit elemments into destination array based on
     101             :  * mask
     102             : 
     103             :     @param dst destination array of u32 elements
     104             :     @param src source array of u32 elements
     105             :     @param mask array of u64 values representing compress mask
     106             :     @param n_elts number of elements in the source array
     107             :     @return number of elements stored in destionation array
     108             : */
     109             : 
     110             : static_always_inline u32
     111     8364320 : clib_compress_u32 (u32 *dst, u32 *src, u64 *mask, u32 n_elts)
     112             : {
     113     8364320 :   u32 *dst0 = dst;
     114    12535610 :   while (n_elts >= 64)
     115             :     {
     116     4171320 :       if (mask[0] == ~0ULL)
     117             :         {
     118     3670310 :           clib_memcpy_u32 (dst, src, 64);
     119     3670310 :           dst += 64;
     120             :         }
     121             :       else
     122      501005 :         dst = clib_compress_u32_x64 (dst, src, mask[0]);
     123             : 
     124     4171320 :       mask++;
     125     4171320 :       src += 64;
     126     4171320 :       n_elts -= 64;
     127             :     }
     128             : 
     129     8364320 :   if (PREDICT_TRUE (n_elts == 0))
     130      416735 :     return dst - dst0;
     131             : 
     132     7947590 :   return clib_compress_u32_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
     133             : }
     134             : 
     135             : static_always_inline u16 *
     136             : clib_compress_u16_x64 (u16 *dst, u16 *src, u64 mask)
     137             : {
     138             : #if defined(CLIB_HAVE_VEC512_COMPRESS_U8_U16)
     139             :   u16x32u *sv = (u16x32u *) src;
     140             :   for (int i = 0; i < 2; i++)
     141             :     {
     142             :       u16x32_compress_store (sv[i], mask, dst);
     143             :       dst += _popcnt32 ((u32) mask);
     144             :       mask >>= 32;
     145             :     }
     146             : #else
     147             :   u32 i;
     148             :   foreach_set_bit_index (i, mask)
     149             :     dst++[0] = src[i];
     150             : #endif
     151             :   return dst;
     152             : }
     153             : 
     154             : /** \brief Compress array of 16-bit elemments into destination array based on
     155             :  * mask
     156             : 
     157             :     @param dst destination array of u16 elements
     158             :     @param src source array of u16 elements
     159             :     @param mask array of u64 values representing compress mask
     160             :     @param n_elts number of elements in the source array
     161             :     @return number of elements stored in destionation array
     162             : */
     163             : 
     164             : static_always_inline u32
     165             : clib_compress_u16 (u16 *dst, u16 *src, u64 *mask, u32 n_elts)
     166             : {
     167             :   u16 *dst0 = dst;
     168             :   while (n_elts >= 64)
     169             :     {
     170             :       if (mask[0] == ~0ULL)
     171             :         {
     172             :           clib_memcpy_fast (dst, src, 64 * sizeof (u16));
     173             :           dst += 64;
     174             :         }
     175             :       else
     176             :         dst = clib_compress_u16_x64 (dst, src, mask[0]);
     177             : 
     178             :       mask++;
     179             :       src += 64;
     180             :       n_elts -= 64;
     181             :     }
     182             : 
     183             :   if (PREDICT_TRUE (n_elts == 0))
     184             :     return dst - dst0;
     185             : 
     186             :   return clib_compress_u16_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
     187             : }
     188             : 
     189             : static_always_inline u8 *
     190             : clib_compress_u8_x64 (u8 *dst, u8 *src, u64 mask)
     191             : {
     192             : #if defined(CLIB_HAVE_VEC512_COMPRESS_U8_U16)
     193             :   u8x64u *sv = (u8x64u *) src;
     194             :   u8x64_compress_store (sv[0], mask, dst);
     195             :   dst += _popcnt64 (mask);
     196             : #else
     197             :   u32 i;
     198             :   foreach_set_bit_index (i, mask)
     199             :     dst++[0] = src[i];
     200             : #endif
     201             :   return dst;
     202             : }
     203             : 
     204             : /** \brief Compress array of 8-bit elemments into destination array based on
     205             :  * mask
     206             : 
     207             :     @param dst destination array of u8 elements
     208             :     @param src source array of u8 elements
     209             :     @param mask array of u64 values representing compress mask
     210             :     @param n_elts number of elements in the source array
     211             :     @return number of elements stored in destionation array
     212             : */
     213             : 
     214             : static_always_inline u32
     215             : clib_compress_u8 (u8 *dst, u8 *src, u64 *mask, u32 n_elts)
     216             : {
     217             :   u8 *dst0 = dst;
     218             :   while (n_elts >= 64)
     219             :     {
     220             :       if (mask[0] == ~0ULL)
     221             :         {
     222             :           clib_memcpy_fast (dst, src, 64);
     223             :           dst += 64;
     224             :         }
     225             :       else
     226             :         dst = clib_compress_u8_x64 (dst, src, mask[0]);
     227             : 
     228             :       mask++;
     229             :       src += 64;
     230             :       n_elts -= 64;
     231             :     }
     232             : 
     233             :   if (PREDICT_TRUE (n_elts == 0))
     234             :     return dst - dst0;
     235             : 
     236             :   return clib_compress_u8_x64 (dst, src, mask[0] & pow2_mask (n_elts)) - dst0;
     237             : }
     238             : 
     239             : #endif

Generated by: LCOV version 1.14