还在初学阶段,边学边写,如果有误,还望多多指正,谢谢!
欢迎加入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(); }