VPP 源码解析 宏 VLIB_NODE_FUNCTION_MULTIARCH

来源:互联网 发布:上帝 知乎 编辑:程序博客网 时间:2024/05/16 08:27

还在初学阶段,边学边写,如果有误,还望多多指正,谢谢!

欢迎加入VPP讨论群:417538415


node.h  VLIB_NODE_FUNCTION_MULTIARCH 宏展开(这里默认宏展开一般都不为空)

#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)\  VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)\  CLIB_MULTIARCH_SELECT_FN(fn, static inline)\  static void __attribute__((__constructor__))\  __vlib_node_function_multiarch_select_##node (void)\  { node.function = fn ## _multiarch_select(); }

接下来我们挨个展开

#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)\  foreach_march_variant(VLIB_NODE_FUNCTION_CLONE_TEMPLATE, fn)
#if __x86_64__ && CLIB_DEBUG == 0#define foreach_march_variant(macro, x) \  macro(avx2,  x, "arch=core-avx2")#else#define foreach_march_variant(macro, x)#endif

把VLIB_NODE_FUNCTION_MULTIARCH_CLONE进一步替换展开

#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)\VLIB_NODE_FUNCTION_CLONE_TEMPLATE(avx2,  fn, "arch=core-avx2")\

宏VLIB_NODE_FUNCTION_CLONE_TEMPLATE定义为

#define VLIB_NODE_FUNCTION_CLONE_TEMPLATE(arch, fn, tgt)\  uword\  __attribute__ ((flatten))\  __attribute__ ((target (tgt)))\  CLIB_CPU_OPTIMIZED\  fn ## _ ## arch ( struct vlib_main_t * vm,\                   struct vlib_node_runtime_t * node,\                   struct vlib_frame_t * frame)\  { return fn (vm, node, frame); }

宏 CLIB_CPU_OPTIMIZED 定义为

#define CLIB_CPU_OPTIMIZED __attribute__ ((optimize ("tree-vectorize")))

上述VLIB_NODE_FUNCTION_CLONE_TEMPLATE(avx2,  fn, "arch=core-avx2")调用替换结果也就是#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)的结果为

 uword\  __attribute__ ((flatten))\  __attribute__ ((target ("arch=core-avx2")))\  __attribute__ ((optimize ("tree-vectorize")))\  fn ## _ avx2 ( struct vlib_main_t * vm,\                   struct vlib_node_runtime_t * node,\                   struct vlib_frame_t * frame)\  { return fn (vm, node, frame); }

继续CLIB_MULTIARCH_SELECT_FN宏展开为

#define CLIB_MULTIARCH_SELECT_FN(fn,...)                               \  __VA_ARGS__ void * fn ## _multiarch_select(void)                     \{                                                                      \  foreach_march_variant(CLIB_MULTIARCH_ARCH_CHECK, fn)                 \  return & fn;                                                         \}

宏foreach_march_variant(CLIB_MULTIARCH_ARCH_CHECK, fn)展开结果

#define CLIB_MULTIARCH_SELECT_FN(fn,...)                               \  __VA_ARGS__ void * fn ## _multiarch_select(void)                     \{                                                                      \  CLIB_MULTIARCH_ARCH_CHECK(avx2, fn, "arch=core-avx2")   \  return & fn;                                                         \}

宏CLIB_MULTIARCH_ARCH_CHECK定义为

#define CLIB_MULTIARCH_ARCH_CHECK(arch, fn, tgt)\  if (clib_cpu_supports_ ## arch())\    return & fn ## _ ##arch;

宏CLIB_MULTIARCH_SELECT_FN最终定义为

#define CLIB_MULTIARCH_SELECT_FN(fn,...)                               \  __VA_ARGS__ void * fn ## _multiarch_select(void)                     \{                                                                      \   if (clib_cpu_supports_ avx2())\    return & fn ## _ avx2;\  return & fn;                                                   \}

宏VLIB_NODE_FUNCTION_MULTIARCH最终结果为

#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)\  uword\  __attribute__ ((flatten))\  __attribute__ ((target ("arch=core-avx2")))\  __attribute__ ((optimize ("tree-vectorize")))\  fn ## _ avx2 ( struct vlib_main_t * vm,\                   struct vlib_node_runtime_t * node,\                   struct vlib_frame_t * frame)\  { return fn (vm, node, frame); }\  static inline void * fn ## _multiarch_select(void)\{                                                                      \   if (clib_cpu_supports_ avx2())\    return & fn ## _ avx2;\  return & fn;                                                   \}\static void __attribute__((__constructor__))\  __vlib_node_function_multiarch_select_##node (void)\  { node.function = fn ## _multiarch_select(); }

举例说明out2in.c:VLIB_NODE_FUNCTION_MULTIARCH (snat_out2in_node, snat_out2in_node_fn);展开结果为

uword\  __attribute__ ((flatten))\  __attribute__ ((target ("arch=core-avx2")))\  __attribute__ ((optimize ("tree-vectorize")))\  snat_out2in_node_fn_ avx2( struct vlib_main_t * vm,\                   struct vlib_node_runtime_t * node,\                   struct vlib_frame_t * frame)\  { return snat_out2in_node_fn(vm, node, frame); }\static inline void * snat_out2in_node_fn_multiarch_select(void)    \{                                                                      \ if (clib_cpu_supports_avx2())\    return & snat_out2in_node_fn_ avx2;\  return & snat_out2in_node_fn;                                                     \}\ static void __attribute__((__constructor__))\  __vlib_node_function_multiarch_select_snat_out2in_node (void)\  { node.function = snat_out2in_node_fn_multiarch_select(); }










0 0