zoukankan      html  css  js  c++  java
  • kfifo

    kfifo 的一些伪代码

     1 kfifo_len()
     2         out = LOAD fifo->out
     3         smp_rmb()
     4         len = LOAD fifo->in - out
     5 
     6 
     7 kfifo_in()                                      kfifo_out()
     8         kfifo_len()                                     kfifo_len()
     9 
    10         smp_mb()                                        smp_rmb()
    11 
    12         off = LOAD fifo->in + off                       off = LOAD fifo->out + off
    13 
    14         /* memcpy */                                    /* memcpy */
    15 
    16         smp_wmb()                                       smp_mb()
    17 
    18         STORE fifo->in += off                           STORE fifo->out += off

    kfifo_in 只修改 fifo->in 的值,含一个 STORE 指令,及若干 fifo->out fifo->in 的 LOAD 指令
    kfifo_out 相反,只修改 kfifo->out 的值,同样含一个 STORE 指令及若干 LOAD 指令

    把代码中的内存屏障去掉

    kfifo_len()
            out = LOAD fifo->out
            /* smp_rmb() */
            len = LOAD fifo->in - out
    
    kfifo_in()                                      kfifo_out()
    
            kfifo_len()                                     kfifo_len()
    
            /* smp_mb() */                                  /* smp_rmb() */
    
            off = LOAD fifo->in + off                       off = LOAD fifo->out + off
    
            /* memcpy */                                    /* memcpy */
    
            /* smp_wmb() */                                 /* smp_mb() */
    
            STORE fifo->in += off                           STORE fifo->out += off



    两个函数的内存访问的会产生干扰的操作位于 kfifo_len() 中,假设现在是单生产者单消费者模式,考虑下面的情况

            kfifo_in()
    t1              out = LOAD fifo->out
    t2              /* smp_rmb() */
    t3              len = LOAD fifo->in - out
    t4              /* smp_mb() */                          kfifo_out()
    t5              off = LOAD fifo->in + off                       out = LOAD fifo->out
    t6              /* memcpy */                                    /* smp_rmb() */
    t7              /* smp_wmb() */                                 len = LOAD fifo->in - out
    t8              STORE fifo->in += off                           /* smp_rmb() */
    t9                                                              off = LOAD fifo->out + off
    t10                                                             /* memcpy */
    t11                                                             /* smp_mb() */
    t12                                                             STORE fifo->out += off
    
    
            kfifo_out()
    t1              out = LOAD fifo->out
    t2              /* smp_rmb() */
    t3              len = LOAD fifo->in - out
    t4              /* smp_rmb() */                         kfifo_in()
    t5              off = LOAD fifo->out + off                      out = LOAD fifo->out
    t6              /* memcpy */                                    /* smp_rmb() */
    t7              /* smp_mb() */                                  len = LOAD fifo->in - out
    t8              STORE fifo->out += off                          /* smp_mb() */
    t9                                                              off = LOAD fifo->in + off
    t10                                                             /* memcpy */
    t11                                                             /* smp_wmb() */
    t12                                                             STORE fifo->in += off

    后执行的函数在 t8 时刻,实际上内存已经写入或者读出,但是 in 和 out 并没有发生改变就被另外一个函数读取。
    而这并不会产生错误,但是写入或者读出的数据都比实时的数据偏小,这也是 kfifo 的高明之处。
    如果出队入队的操作特别频繁的话,对结果没影响。

    若是要保持实时的顺序,即 t6 -> t8,一个函数的 memcpy 操作立刻对另一个 memcpy 可见,所以需要采取一些辅助措施来保证这个效果。

  • 相关阅读:
    Java中的Graphics2D类基本使用教程
    JSP中页面向Action传递参数的几种方式
    中英文统计
    numpy数据集练习 ----------sklearn类
    IDEA在jsp页面写out.print()代码报错
    Tag文件的创建与应用
    Intellij部署Tomcat问题
    单例测试模式中【饿汉式】与【懒汉式】的区别
    java中类与方法叙述正确的是
    下列关于异常处理的描述中,错误的是()。
  • 原文地址:https://www.cnblogs.com/shuqin/p/11391536.html
Copyright © 2011-2022 走看看