linux内核中的宏ffs(x)

 

linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在

arch/arm/include/asm/bitops.h

#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })

__t & -__t   等于找到__t 第一个为1的位(从低位开始),并把该位保留为1其余位清0.

例如 一32位整形数 6,用二进制表示它的低8位:00000110,  都知道负数为最高为1其余位取反加1.-6即 11111010

相与得 00000010,即6&-6. 把该值传递给函数fls().

再看fls函数.

if (__builtin_constant_p(x))
return constant_fls(x);

__builtin_constant_p 是Gcc的内建函数 ,用于判断一个值是否为编译时常数,如果参数的值是常数,函数返回 1,否则返回 0。

如果是常数就用下面函数计算00000010中1的位置

static inline int constant_fls(int x)
{
int r = ; if (!x)
return ;
if (!(x & 0xffff0000u)) {
x <<= ;
r -= ;
}
if (!(x & 0xff000000u)) {
x <<= ;
r -= ;
}
if (!(x & 0xf0000000u)) {
x <<= ;
r -= ;
}
if (!(x & 0xc0000000u)) {
x <<= ;
r -= ;
}
if (!(x & 0x80000000u)) {
x <<= ;
r -= ;
}
return r;
}

算法就是折半法,这个函数计算的是从高位起第一个1位的位置.00000010, r=2.  由于__t&-__t只有一个1,所以就是找到该1的位置.

如果输入参数是00001010 那么 r=4.

如果参数是变量,直接使用arm指令运算.

执行

asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
ret = - ret;

CLZ(Count Leading Zeros)指令对Rm中值的高位(leading zeros)个数进行计数,结果放到Rd中。若源寄存器全为0,则结果为32。若[31]为1,则结果为0。

clz指令计算高位0的个数, 然后拿32-ret 算出1的位置.

所以,ffs(x)这个宏的值就是x的第一个1的位置(从低位开始,数值从1开始,0代表x全0).

另外,该文件中还有很多linux关于位操作的函数,可以作为自己写应用程序时的有用参考.

ffs, fls的更多相关文章

  1. linux内核中的宏ffs(x)

    linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...

  2. sql monitor生成不了报告& FFS hint不生效两个问题思考

    事情的发生就是这么偶然,一步步的深入才能汲取到更深入的知识~~ -------------------START------------------------------------------- ...

  3. index ffs、index fs原理考究-1109

    h2 { margin-top: 0.46cm; margin-bottom: 0.46cm; direction: ltr; line-height: 173%; text-align: justi ...

  4. 基于faro SDK 读取fls原始文件

    #define _SCL_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include <iostream> //#include ...

  5. 【从翻译mos文章】采用高速全扫描索引(index ffs) 为了避免全表扫描

    采用高速全扫描索引(index ffs) 为了避免全表扫描 参考原始: Index Fast Full Scan Usage To Avoid Full Table Scans (Doc ID 701 ...

  6. 2019.06.18训练日记(赞FLS)

    之前打了几场比赛,有很多题没做出来,这些题无论是知识点不会,还是说在当时时间和思路的影响下没有做出来,这都应该做出来,至少现在必须做出来,本来打算专心复习,分数高了,好保研,但是想了想如果局限于只把学 ...

  7. 实战ffs函数

    这个函数是返回整形的最低位1的位置 自己写是这个样子的: /* Find the first bit set in I. */ int lx_ffs(int i) { int index = 0, r ...

  8. Git FLS的使用

    克隆git地址后,一些文件内容被隐藏. 显示如下: version https://git-lfs.github.com/spec/v1oid sha256:xxxxxxxxxxxxxxxxxxxxx ...

  9. spingMVC<1>-xml文件配置

    ---恢复内容开始---

随机推荐

  1. 通过泛型,将string转换为指定类型

    Generic TryParse You should use the TypeDescriptor class: public static T Convert<T>(this stri ...

  2. 79、tensorflow计算一个五层神经网络的正则化损失系数、防止网络过拟合、正则化的思想就是在损失函数中加入刻画模型复杂程度的指标

    ''' Created on Apr 20, 2017 @author: P0079482 ''' import tensorflow as tf #获取一层神经网络边上的权重,并将这个权重的L2正则 ...

  3. 06、python的基础-->编码小知识

    1.编码类型ascii A : 00000010 8位 一个字节 unicode A : 00000000 00000001 00000010 00000100 32位 四个字节 中:00000000 ...

  4. 字母所对应的Unicode编码

    A~Z                65~90 a~z                 97~122 public class Unicode { public static void main(S ...

  5. mysql 密码

    http://www.cnblogs.com/jonsea/p/5510219.html character-set-server=utf8 mysql 修改密码: ALTER USER 'root' ...

  6. 把我坑惨的一个MySQL双引号!

    来源:For DBA www.fordba.com/mysql-double-quotation-marks-accident.html 一.前言 最近经常碰到开发误删除误更新数据,这不,他们又给我找 ...

  7. Spring Cloud Eureka自我保护机制

    自我保护背景 首先对Eureka注册中心需要了解的是Eureka各个节点都是平等的,没有ZK中角色的概念, 即使N-1个节点挂掉也不会影响其他节点的正常运行. 默认情况下,如果Eureka Serve ...

  8. zookeeper和dubbo可视化软件的使用

    1. zookeeper的可视化软件使用 Zkui 1. 下载软件 https://github.com/DeemOpen/zkui.git 2. 解压编译  clean install 会在targ ...

  9. 观察者模式JDK源码解析

    由于JDK中为了方便开发人员,已经写好了现成的观察者接口和被观察者类. 先来观察者接口: //观察者接口,每一个观察者都必须实现这个接口 public interface Observer { //这 ...

  10. bzoj4544 椭圆上的整点

    我会所有推理..... Q1:真的这么暴力的统计答案? Q2:蜜汁统计答案.... Q3:为什么不考虑3在不同的位置的情况