VPP 源码解析 宏 VLIB_NODE_FUNCTION_MULTIARCH

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

欢迎加入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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值