vpp之clib.h分析
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分析的更多相关文章
- ioctl.h 分析
ioctl.h 分析 我自己画了个解析图...不要嫌弃丑啊.. . 哈哈 type The magic number. Just choose one number (after consulting ...
- SGI STL源码stl_vector.h分析
前言 vector 是最常用的 C++ 容器,其动态扩容的特性是普通数组不具备的,这大大增加了编程的灵活性.虽然平时用 vector 很多,也能基本理解其原理,但无法从深层次理解.直到研读了 vect ...
- ios的xxxAppDelegate.h分析
#import "BIDAppDelegate.h" #import "BIDViewController.h" @implementation BIDAppD ...
- SGI STL源码stl_bvector.h分析
前言 上篇文章讲了 STL vector 泛化版本的实现,其采用普通指针作为迭代器,可以接受任何类型的元素.但如果用来存储 bool 类型的数据,可以实现功能,但每一个 bool 占一个字节(byte ...
- String源码分析
前言:String类在日常开发过程中使用频率非常高,平时大家可能看过String的源码,但是真的认真了解过它么,笔者在一次笔试过程中要求写出String的equals方法,瞬间有点懵逼,凭着大致的理解 ...
- hashCode()方法源码分析
执行代码 public class Demo06 { public static void main(String[] args) { String s="hello"; Syst ...
- Linux Linux程序练习十五(进程间的通信共享内存版)
/* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2.子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进 ...
- C语言 百炼成钢3
//题目7:用*号输出空心菱形图案 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> # ...
- C语言 百炼成钢2
//题目4:输入某年某月某日,判断这一天是这一年的第几天? #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<st ...
随机推荐
- CSS小功能实现
1.css实现三角形效果 #prev { display: block; width:; height:; border-bottom: 7px solid #4d4d4f; border-right ...
- Spring Boot入门系列(十八)整合mybatis,使用注解的方式实现增删改查
之前介绍了Spring Boot 整合mybatis 使用xml配置的方式实现增删改查,还介绍了自定义mapper 实现复杂多表关联查询.虽然目前 mybatis 使用xml 配置的方式 已经极大减轻 ...
- 【Spring】Bean的LifeCycle(生命周期)
菜瓜:水稻,上次说Bean的LifeCycle,还没讲完 水稻:啥?说人话? 菜瓜:spring,bean,生命周期 水稻:哦哦,下次直接说人话.说正事,先从BeanFactory.Applicati ...
- 2020年最佳Java调试工具(翻译)
调试是应用程序开发周期不可或缺的一部分.用Java或任何其他语言编写程序时,每个开发人员应解决的首要问题之一是可靠的调试工具的可用性. 所使用的工具类型可能影响或破坏应用程序的调试过程,因此至关重要的 ...
- Golang简易入门教程——面向对象篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第9篇文章,我们一起来看看golang当中的面向对象的部分. 在现在高级语言当中,面向对象几乎是不可或缺也是一门语言 ...
- ssh生成单个公钥
ssh生成单个公钥命令: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" 查看公钥: cat ~/.ssh/id_rsa ...
- NodeJs将异步方法改为同步以上传文件为例
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 下面这个例子既写 ...
- C#数据结构与算法系列(十二):递归(Recursion)
1.介绍 简单的说:递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时也让代码变得整洁 2.规则 执行一个方法时,就创建一个新的受保护的独立空间(栈空间) 方法的 ...
- DataOutputStream是用来处理什么类型数据的
FileOutputStream f=new FileOutputStream(new File("sa.txt")); DataOutputStream do=new DataO ...
- java 中对hashmap进行排序
public class HashMapSort { public static void main(String[] args) { HashMap<Integer, Student> ...