ZYNQ中ARM架构简析(1)——Cache和Branch Prediction

ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第1张图片
zynq 7000系列作为xilinx公司最具性价比的SOC系列,在消费市场大受欢迎。其内部配置一个或两个ARM架构的cortex A9核,对于管理调度有重大意义,同时在ARM侧(专业叫法为PS侧)配置了uart,iic,ethernet,flash,ddr等多个接口,不再需要FPGA侧(PL侧)针对这些接口再做控制器,使用起来更加方便,当然效率肯定不如纯FPGA来的高。
这篇文章只是分析一下PS侧的ARM架构,也是记录我自己学习的过程,完成从FPGA到嵌入式的转变。
ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第2张图片

1.Cache
cache可能被分为L1, L2, L3, 越往外,访问时间也就越长,但同时也就越便宜。L1 cache命中时,访问时间为1~2个CPU周期;
L1 cache不命中,L2 cache命中,访问时间为5~10个CPU周期。
当要去内存中取单元时,访问时间可能就到25~100个CPU周期了。
所以,我们总是希望cache的命中率尽可能的高。
关于Cache的原理,可参见:https://blog.csdn.net/orange_os/article/details/7853355
该博文中一个非常有用的例子,记录了什么样的操作更利于Cache的操作(该例子是在单核运行时;如果是多核运行,只要不同的线程或者进程访问同一cacheline的不同内容,就会发生“伪共享问题”。这样的问题较为隐蔽,难以发现。)。
Cache友好的代码:
由于一般的机器中,C语言数组都是按行优先存储的。假设Cacheline的大小为B个字节,Cache总容量为C字节,直接映射存储方式,那么一共有C/B行Cacheline。对于a[M][N]这个MN个字节。每每读到第 nB 个数组元素时( 0N/B ),才会发生cache miss,因此至多发生 MN/B 次cache miss,不命中率至多为 (MN/B)/(MN) = 1/B。
Cache不友好的代码:
这个代码是按列优先访问的,情况要复杂一些。我们只看一种比较简单的情况:
当 N=B , MN > C, E是cacheline的行数,即为C/B。 看看会发生什么:在访问a[0][0]~a[E-1][0]时,每次都会造成Cache miss,然后访问a[E][0]a[M-1][0]时,又会把第0M-E-1行cacheline给覆盖掉,因此当访问a[0][0]~a[M-1][0]时总是会造成Cache miss。在访问a[0][1]a[M-1][1]时,分为2个过程,前0M-E-1行由于被覆盖了,故而Cache又会不命中,而在第M-E~E-1行中, 也就是访问a[M-E][1]~a[E-1][1]时,由于没有被覆盖,这些行将会命中。因此总共有 M+2*(M-E)(N-1)次cache miss。不命中率可算得:2-2E/M-1/N+2E/(MN)。可见,当M>=2E时,不命中率>=1。
当赋予M,N较大值时,测试结果将会是列优先访问程序的运行时间远远大于行优先访问程序运行时间。*

  • L1 cache
    回到Zynq架构中, L1-Cache与内核工作在相同的频率,分为指令Cache和数据Cache。每个都为32KB。
    L1-Cache中每个cacheline为32bytes,也就是整个cache包含1K个cacheline。在进行cache替换过程中,采用伪随机的round-robin方式或者伪随机方式,随机的来源是发生cache miss的时间,需要注意的是,当存在invalid line时,优先填充这些line。
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第3张图片
    对于d-cache,有一些特殊的性质:
    只支持write back/write allocate操作模式,并不支持write through, write back/no write allocate这两种操作模式。具体的区别:http://www.mamicode.com/info-detail-2032670.html
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第4张图片
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第5张图片
  • L2 cache
  1. Branch Prediction
    当前cpu在运行过程中,均采用pipeline模式提高运行效率。假设pipeline分为10个周期,每条指令都需要执行10个周期,则遇到条件判断语句时,下一条指令则无法继续执行,需要等待条件判断结果产生后在跳转到相应的地址执行之后的指令,如下图所示。
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第6张图片
    因此,在cpu中,实现了branch prediction,用来预测当前条件判断的结果,从而提前将跳转指令加载进入pipeline,这也被称为Speculative Execution。预测结果的指令运行出结果后,不会直接输出pipeline,而需要将预测分支结果跟条件判断结果比较,如果正确则输出即可;当然,预测肯定会出现错误的情况,当遇到错误的时候,则需要清空当前pipeline中的预测指令,重新加载正确的跳转指令,会导致损失更多的运行周期。
    因此,好的prediction策略至关重要。具体实现可见此博主的文章:https://www.cnblogs.com/TaigaCon/p/7791303.html
    回到ZYNQ中的ARM架构:
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第7张图片
    在这里插入图片描述
    此架构中,主要采用动态匹配每个local history table的2-bit状态转移历史,所有的branch总共包含4096个entry,同时,可以配合branch target address cache(BTAC)实现类似agree predictor架构。BTAC根据特定的branch将两个分支的地址预取到unit中,方便直接获取。
    ZYNQ中ARM架构简析(1)——Cache和Branch Prediction_第8张图片

你可能感兴趣的:(ARM,ZYNQ,CACHE,BRANCH,PREDICTION)