vpp代码中有一个clib.h,其中封装了很一些很经典的位运算:

 //计算以2为底的对数,log2(x)
//也就是计算2的N次方为x。x为uint32类型
#if defined (count_leading_zeros)
always_inline uword
min_log2 (uword x)
{
uword n;
n = count_leading_zeros (x);
return BITS (uword) - n - ;
}
#else
always_inline uword
min_log2 (uword x)
{
uword a = x, b = BITS (uword) / , c = , r = ; /* Reduce x to 4 bit result. */
#define _ \
{ \
c = a >> b; \
if (c) a = c; \
if (c) r += b; \
b /= ; \
} if (BITS (uword) > )
_;
_;
_;
_;
#undef _ /* Do table lookup on 4 bit partial. */
if (BITS (uword) > )
{
const u64 table = 0x3333333322221104LL;
uword t = (table >> ( * a)) & 0xf;
r = t < ? r + t : ~;
}
else
{
const u32 table = 0x22221104;
uword t = (a & ) ? : ((table >> ( * a)) & 0xf);
r = t < ? r + t : ~;
} return r;
}
#endif //计算以2为底的对数(有余数的话+1),log2(x)
//也就是计算2的N次方为x。2的N次方大于x
always_inline uword
max_log2 (uword x)
{
uword l = min_log2 (x);
if (x > ((uword) << l))
l++;
return l;
} //计算以2为底的对数,log2(x)
//也就是计算2的N次方为x。x为u64类型
always_inline u64
min_log2_u64 (u64 x)
{
if (BITS (uword) == )
return min_log2 (x);
else
{
uword l, y;
y = x;
l = ;
if (y == )
{
l += ;
x >>= ;
}
l += min_log2 (x);
return l;
}
} //计算基数2的x次幂的值对应的掩码
//比如2的4次幂为16,对应的掩码为15
always_inline uword
pow2_mask (uword x)
{
return ((uword) << x) - (uword) ;
} //计算数字x对应的,以基数2的n次幂的值。x小于等于n
//比如x=15,则得出的数字为16.2的3次幂小于x,2的4次幂大于x。
always_inline uword
max_pow2 (uword x)
{
word y = (word) << min_log2 (x);
if (x > y)
y *= ;
return y;
} //计算x是否可等于基数2的n次幂
//比如x=16,返回1.x=15,返回0
always_inline uword
is_pow2 (uword x)
{
return == (x & (x - ));
} //计算x以pow2对齐的长度。pow2应该为2的n次方。
//如x=15,pow2=4,则返回16。
always_inline uword
round_pow2 (uword x, uword pow2)
{
return (x + pow2 - ) & ~(pow2 - );
} //计算x以pow2对齐的长度。pow2应该为2的n次方。
//如x=15,pow2=4,则返回16。
always_inline u64
round_pow2_u64 (u64 x, u64 pow2)
{
return (x + pow2 - ) & ~(pow2 - );
} //保留二进制下最后出现的1的位置,其余位置置0(即一个数中最大的2的n次幂的因数
//当一个偶数与它的负值向与时,结果是能被这个偶数整除的最大的2的n次幂
//当一个奇数与它的负值向与时结果一定是1
always_inline uword
first_set (uword x)
{
return x & -x;
} //先将x用first_set计算结果,
//然后以2为底做对数运算
always_inline uword
log2_first_set (uword x)
{
uword result;
#ifdef count_trailing_zeros
result = count_trailing_zeros (x);
#else
result = min_log2 (first_set (x));
#endif
return result;
} //将浮点数强转为整型(小数部分舍去)
always_inline f64
flt_round_down (f64 x)
{
return (int) x;
} //将浮点数强转为整型(小数部分四舍五入)
always_inline word
flt_round_nearest (f64 x)
{
return (word) (x + .);
} //若x大于f的一半,则返回f,否则返回0
always_inline f64
flt_round_to_multiple (f64 x, f64 f)
{
return f * flt_round_nearest (x / f);
} //计算x右移start位后,再截取count位有效数字是多少
always_inline uword
extract_bits (uword x, int start, int count)
{
#ifdef __BMI__
return _bextr_u64 (x, start, count);
#endif
return (x >> start) & pow2_mask (count);
} //取x和y两个数中大的数
#define clib_max(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x > _y ? _x : _y; \
}) //取x和y两个数中较小的数
#define clib_min(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x < _y ? _x : _y; \
}) //取x和y两个数中较大的数
#define clib_max(x,y) \
({ \
__typeof__ (x) _x = (x); \
__typeof__ (y) _y = (y); \
_x > _y ? _x : _y; \
}) //取x的绝对值
//定义类型与x相同的临时变量_x,并将x的值赋予_x
//取绝对值
#define clib_abs(x) \
({ \
__typeof__ (x) _x = (x); \
_x < ? -_x : _x; \
})

vpp之clib.h分析的更多相关文章

  1. ioctl.h 分析

    ioctl.h 分析 我自己画了个解析图...不要嫌弃丑啊.. . 哈哈 type The magic number. Just choose one number (after consulting ...

  2. SGI STL源码stl_vector.h分析

    前言 vector 是最常用的 C++ 容器,其动态扩容的特性是普通数组不具备的,这大大增加了编程的灵活性.虽然平时用 vector 很多,也能基本理解其原理,但无法从深层次理解.直到研读了 vect ...

  3. ios的xxxAppDelegate.h分析

    #import "BIDAppDelegate.h" #import "BIDViewController.h" @implementation BIDAppD ...

  4. SGI STL源码stl_bvector.h分析

    前言 上篇文章讲了 STL vector 泛化版本的实现,其采用普通指针作为迭代器,可以接受任何类型的元素.但如果用来存储 bool 类型的数据,可以实现功能,但每一个 bool 占一个字节(byte ...

  5. String源码分析

    前言:String类在日常开发过程中使用频率非常高,平时大家可能看过String的源码,但是真的认真了解过它么,笔者在一次笔试过程中要求写出String的equals方法,瞬间有点懵逼,凭着大致的理解 ...

  6. hashCode()方法源码分析

    执行代码 public class Demo06 { public static void main(String[] args) { String s="hello"; Syst ...

  7. Linux Linux程序练习十五(进程间的通信共享内存版)

    /* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2.子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进 ...

  8. C语言 百炼成钢3

    //题目7:用*号输出空心菱形图案 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...

  9. C语言 百炼成钢2

    //题目4:输入某年某月某日,判断这一天是这一年的第几天? #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<st ...

随机推荐

  1. 四分位数与pandas中的quantile函数

    四分位数与pandas中的quantile函数 1.分位数概念 统计学上的有分位数这个概念,一般用p来表示.原则上p是可以取0到1之间的任意值的.但是有一个四分位数是p分位数中较为有名的. 所谓四分位 ...

  2. 【服务器】VMware Workstation Pro虚拟机搭建本地服务器CentOs7和宝塔面板(保姆式教程)

    内容繁多,请耐心跟着流程走,在过程中遇到问题请在下面留言. 前言 这几天一直在复习thinkphp5.1,学习环境是phpStudy8.1,但是遇到了文件有缓存的问题(thinkphp5.1.39,修 ...

  3. 入门大数据---Python基础

    前言 由于AI的发展,包括Python集成了很多计算库,所以淡入了人们的视野,成为一个极力追捧的语言. 首先概括下Python中文含义是蟒蛇,它是一个胶水语言和一个脚本语言,胶水的意思是能和多种语言集 ...

  4. onunload对应的js代码为什么不能执行?和onbeforeunload的区别?

    为什么onunload对应的js代码不能执行? 为什么onbeforeunload才可以在离开页面时执行相应的js代码? 1.onunload和onbeforeunload都是在离开页面或者刷新页面的 ...

  5. Eclipse中Debug时鼠标悬停不能查看变量值解决办法

    问题描述:Eclipse在Debug模式下,当鼠标移动到某个变量上面时不自动显示该变量对应的值. 解决方法:在Eclipse中点击 Window->Preferences->Java-&g ...

  6. css设置边框阴影;box-shadow的使用

    html代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  7. Linux 操作系统!开篇!!!

    此篇文章主要会带你介绍 Linux 操作系统,包括 Linux 本身.Linux 如何使用.以及系统调用和 Linux 是如何工作的. Linux 简介 UNIX 是一个交互式系统,用于同时处理多进程 ...

  8. asp.net core 发布包含文件

    这样这个文件在发布的时候,就会包含进去了.

  9. 利用 React 高阶组件实现一个面包屑导航

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...

  10. css中vertical-aling与line-height

    基线 baseline:字符x的底部 x-height: 字母x的高度,vertical-aling设置为middle的时候,对齐的是baseline往上1/2的x-height,所以vertical ...