summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/vector_avx512.h
blob: f69c67e697cd42ff091d42e46f92bf8e807ac708 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef included_vector_avx512_h
#define included_vector_avx512_h

#include <vppinfra/clib.h>
#include <x86intrin.h>

/* *INDENT-OFF* */
#define foreach_avx512_vec512i \
  _(i,8,64,epi8) _(i,16,32,epi16) _(i,32,16,epi32)  _(i,64,8,epi64)
#define foreach_avx512_vec512u \
  _(u,8,64,epi8) _(u,16,32,epi16) _(u,32,16,epi32)  _(u,64,8,epi64)
#define foreach_avx512_vec512f \
  _(f,32,8,ps) _(f,64,4,pd)

/* splat, load_unaligned, store_unaligned, is_all_zero, is_equal,
   is_all_equal, is_zero_mask */
#define _(t, s, c, i) \
static_always_inline t##s##x##c						\
t##s##x##c##_splat (t##s x)						\
{ return (t##s##x##c) _mm512_set1_##i (x); }				\
\
static_always_inline t##s##x##c						\
t##s##x##c##_load_unaligned (void *p)					\
{ return (t##s##x##c) _mm512_loadu_si512 (p); }				\
\
static_always_inline void						\
t##s##x##c##_store_unaligned (t##s##x##c v, void *p)			\
{ _mm512_storeu_si512 ((__m512i *) p, (__m512i) v); }			\
\
static_always_inline int						\
t##s##x##c##_is_all_zero (t##s##x##c v)					\
{ return (_mm512_test_epi64_mask ((__m512i) v, (__m512i) v) == 0); }	\
\
static_always_inline int						\
t##s##x##c##_is_equal (t##s##x##c a, t##s##x##c b)			\
{ return t##s##x##c##_is_all_zero (a ^ b); }				\
\
static_always_inline int						\
t##s##x##c##_is_all_equal (t##s##x##c v, t##s x)			\
{ return t##s##x##c##_is_equal (v, t##s##x##c##_splat (x)); }		\
\
static_always_inline u##c						\
t##s##x##c##_is_zero_mask (t##s##x##c v)				\
{ return _mm512_test_##i##_mask ((__m512i) v, (__m512i) v); }		\


foreach_avx512_vec512i foreach_avx512_vec512u
#undef _
/* *INDENT-ON* */

static_always_inline u32
u16x32_msb_mask (u16x32 v)
{
  return (u32) _mm512_movepi16_mask ((__m512i) v);
}

#endif /* included_vector_avx512_h */
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
cl_vec_for_context(lc_index, acl_list). The first parameter specifies the context that you have created, the second parameter is a vector of u32s, each u32 being the index of the ACL which we should be looking up within this context. The comand is idempotent, i.e. it unapplies the previously applied list of ACLs, and then sets the new list of ACLs. Subsequent ACL updates for the already applied ACLs will cause the re-application on an as-needed basis. Note, that the ACL application is potentially a relatively costly operation, so it is only expected that these changes will be done in the control plane, NOT in the datapath. The matching within the context is done using two functions - acl_plugin.fill_5tuple() and acl_plugin.match_5tuple() and their corresponding inline versions, named acl_plugin_fill_5tuple_inline() and acl_plugin_match_5tuple_inline(). The inline and non-inline versions have the equivalent functionality, in that the non-inline version calls the inline version. These two variants are provided for debugging/maintenance reasons. When you no longer need a particular context, you can return the allocated resources by calling acl_plugin.put_lookup_context_index() to mark it as free. The lookup structured associated with the vector of ACLs set for the lookup are cleaned up automatically. However, the ACLs themselves are not deleted and are available for subsequent reuse by other lookup contexts if needed. There is one delicate detail that you might want to be aware of. When the non-inline functions reference the inline functions, they are compiled as part of ACL plugin; whereas when you refer to the inline functions from your code, they are compiled as part of your code. This makes referring to a single acl_main structure a little trickier. It is done by having a static p_acl_main within the .h file, which points to acl_main of the ACL plugin, and is initialized by a static constructor function. This way the multiple includes and inlines will "just work" as one would expect. Debug CLIs ========== To see the state of the ACL lookup contexts, you can issue "show acl-plugin lookup user" to see all of the users which registered for the usage of the ACL plugin lookup contexts, and "show acl-plugin lookup context" to show the actual contexts created. You will notice that the latter command uses the values supplied during the module registration in order to make the output more friendly. The "show acl-plugin acl" and "show acl-plugin interface" commands have also acquired the notion of lookup context, but there it is used from the client perspective, since with this change the interface ACL lookup itself is a user of ACL lookup contexts.