zoukankan      html  css  js  c++  java
  • 就绪表

    就绪表

    • 适用于理解ucosII任务优先级,以及资源管理分配等

    在开始阅读之前,我希望你能明白以下的一些基本的思想,对于理解后续的内容有一定的相关性。

    1. 对于非有即无的东西,为了尽量的节约空间占用,我们可以用1bit来表示信息。
    2. 对于程序中空间与时间的取舍,绝大部分情况下灰采用空间换取时间,毕竟时间就是金钱。

    ucos-II之任务优先级

    在ucos-II中,支持64个优先级,那么怎么查找最高优先级,以及优先级的设置,清除等,抛开书中讲的,你会怎么实现?

    方法一:

    bool Priodata[64] = {0},具体如何做,这个就是通过for循环来查表了,从Priodata[0]元素查询到[63],查到该元素的数字为1为止。

    方法二:
    • 既然都是bool型的,为什么不能用1bit来表示?何必浪费7倍的bit来表示?

    所以有了如下:

    /* 8*8的bit数 */
    PrioTable[8] = {0};
    

    以下是图:

    思路:伪代码,应该都会看的懂(没有做其他的一些处理。)

      for i in 0 to 8:
        if PrioTable[i] != 0:
          for j in 0 to 8:
            if (PrioTable[i] & (1 << j)) == 1:
              return i*8 + j
    

    很多时候,如果能写出以上的代码,是对空间的利用更好的一点,但是,还是要经过循环(有的时候会嵌套)来达到查询的目的,是否有一种方法能有效的减少查询的次数呢?所以,这里引进一个数据,专门用来存储表示一些信息。

    方法三:
    • 数据的压缩,来表示整体,即增加限定词。

    PS:不得不说,现实世界中处处存在这样的情况。如果要在某个小区找某一户,首先,我们会限定在那一栋,哪一个单元,哪一个楼层等等。

    在这里,增加一组数据表示PrioTable[8]中当前某一个数据是否存在数据。本着节约资源的原则,我们定义一个数据:

    uint8 GrpData = 0;
    以下是图:

    为了方便强迫症患者,把它旋转为主流的样子:

    这个东西来表示什么的呢?就是用来表示PrioTable[i]中第i个元素是否有值存在.

    所以,查找最高优先级这种游戏就变成了:

    1. 查找GrpData数据中从bit0-bit7中最低为1的位
    2. 查找对应的PrioTable[i]中从bit0-bit7中最低为1的位.

    PS:理解了以上这两句话的可以不用看下面的。

    既然都是查找uint8中的最低为1的位,有几种方法:

    1. 循环查找
    2. 查表查找

    前面一种就不用说了,说后面这种,最简单的办法就是,将uint8所能表示的数字来一个全遍历,存起来,直接索引!
    所以,对于有:

    1. 0000,0000没找到,为0
    2. 0000,0001为bit0,为0
    3. 0000,0010为bit1,为1.
    4. 0000,0011为bit0,为0
    5. 0000,0100为bit2,为2

    依次类推,这个可以通过程序生成,附带优先级查找表:

    那么找到了GrpData最低位x,与PrioTable[x]中最低位y(注意其中的x),有几种方法可以得到当前的优先级:

    1. x表示第几组.
    2. y表示第几列.

    所以 x*8 + y,如果是不喜欢用乘法的童鞋,肯定会将以上的乘法修改为x<<3 + y
    到此,大体可以结束了的,有兴趣可以看看下面。

    数的组合与位信息表示

    很多解释上面那个x<<3的时候,解释的不是很清楚,我说说自己的理解。
    在计算机或者自然科学中,都存在有效位一说,特别是计算机中,涉及到LSB,MSB等。
    在对数据进行分组的时候,我们可以将数据进行拆分:

    以上图为例,我们将16个数据组成为一组,当满了16个数据以后,前进一位(溢出),用高位上的数据位来表示,是不是很像16进制?数据的组合其实也是这样子的。
    在就绪表中,我们将8个数据组合为1组,即通过一个uint8的后三位表示一组中的某个元素,以前面的高位来表示是第几组的数据。
    所以,如果后期不是64个优先级,需要扩展或者压缩,可以通过这种分组的方式进行思考,相应的把GrpData的数据进行扩展/缩减,当然扩展的话就不能用uint8来表示了,这个需要用到循环一次的方式来表示。大体方法类似。

    优先级的写入与清除

    对于位操作的写入与清除,有几个很有用的位操作运算。具体的可以看我以前写的关于怎么给某一位写1与写0(即清除).(PS:貌似没找到,大概说一下:)

    • 写1:
    • PrioTable[i] |= (1<<j)
    • 写0:
    • PrioTable[i] &= (~(1<<j))

    当然,还有其他的方法进行写和清除。
    那么,如何做到匹配以上的思想呢?那么再创建一个MaskTable.
    MaskTable[8] = {1,2,4,8,16,32,64,128};可以直接得到的最低位索引这个表格,然后将对应的位写入进去。

    资源管理表

    前面说到的是查找第一个为1的数即为第一个优先级。既然查找1都有,为什么没有查找0呢?什么时候去查找0,查找0的查找表又是什么样子的?
    在资源的使用上,经常会用类似的方式来标定那些资源已经被使用,那么没有被使用,如果没有被使用,肯定优先使用某一部分的资源(按照某一个可以遵循的规则)。

    比如说:优先使用前面的,那是不是需要查找第一个为0的数据?
    算法类似,只是256的表不同。
    0. 0000,0000bit0,为0

    1. 0000,0001bit1,为1
    2. 0000,0010bit0,为0.
    3. 0000,0011bit2,为2
    4. 0000,0100bit0,为0
      依次,也可通过程序生成,类似于这种图:
  • 相关阅读:
    Coursera机器学习week11 单元测试
    关于 TypeReference 的解释
    getModifiers 方法解释。
    instanceof isInstance isAssignableFrom 比较
    elasticsearch 基础 语法总结
    kibana 启动 关闭 和进程查找
    MD5 SHA1 SHA256 SHA512 SHA1WithRSA 的区别
    spring boot 项目 热启动
    java zip 压缩文件
    Packet for query is too large (1660 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.
  • 原文地址:https://www.cnblogs.com/ply616/p/5713246.html
Copyright © 2011-2022 走看看