蜗窝科技

ARM CPU性能实验

linuxer · · 阅读 19631 · 2015年4月存档

一、前言

一般工程师的直觉是当提升了CPU的运行频率,那么性能应该是呈现线性的关系,例如如果CPU跑260MHz,当降低到130MHz后,其性能应该会降低一半。实际情况如何呢?我们来做一个实验看看。

二、实验

1、实验环境介绍

硬件平台当然是强大的,生命期超长,死而复生(2010年就phase out了,但仍然有一批人马顽强的在上面开发)的AD6900处理器了。除此之外,还需要一台示波器用来测量时间。

2、在kernel中测试

实验方法如下:
(1)设置AD6900 ARM core所需的clock(260、130,65,32.5)

(2)使用linux中udelay函数(当然,kernel中udelay是和loops per jiffy相关,我们需要稍加修改,让他仅在260MHz的时候能够正确的delay)的方式进行延时

(3)通过GPIO翻转来确定起始和结束的时间点

(4)用示波器测量方波脉宽,记录实验数据。

实验结果如下:

clockudelay的执行时间
2602.5ms
1305.0ms
6510ms
32.520ms

基本上,在260MHz中执行2.501ms的程序,在130MHz上执行了5.081ms的时间,在32.5MHz上执行了20.64ms,基本上CPU运行clock和程序执行时间呈现线性的关系。

3、在bootloader中测试

同样的实验,我们在bootloader中重复进行,udelay有两个版本,一个是c语言的版本,一开始代码如下:

void delay( void )
{
int cnt = 20000;
while(cnt—);
}

编译之后,delay函数没有任何效果。当然由于开了O2的优化,实际上上面的函数都被优化掉了,要不改成全局变量试一试:

int cnt = 20000;
void delay( void )
{
while(cnt–);
}

情况依然,由于强大的编译器知道delay函数执行到最后cnt等于-1,因此,在delay函数中就偷懒,直接给cnt赋值-1,优化掉了–操作和while判断,当然,给cnt变量加上volatile的修饰符应该是OK了,我们采用了简单的去掉O2优化的方法,得到了下面的结果:

clockudelay的执行时间
2602.610ms
1303.720ms
654.630ms
32.59.242ms

好象结果已经不是那么线性了。怎么回事,要不用汇编写,这样会更直接一些,代码如下:

400202f4 <__delay>:
400202f4: e2500001 subs r0, r0, #1 ; 0x1
400202f8: 8afffffd bhi 400202f4 <__delay>

当然,在执行__delay函数之前,要传递初值给r0寄存器。OK,代码已经完全和linux中的一致了,测试结果如下:

clockudelay的执行时间
2602.5ms
1302.5ms
652.5ms
32.55ms

呵呵,结果多么的神奇。

三、分析

1、和程序执行相关的HW block如下图所示:

cpu block

上图只是画出和本次实验有关的block。

2、kernel中的程序执行过程描述

内核态的delay函数虽然代码位于SDRAM,但是由于:

(1)TLB已经保存了地址映射

(2)指令已经被加载到cacheline

因此,实际上程序的执行基本是是限制在了ARM core内,不需要通过bus访问类似SRAM或者SDRAM的bus slave设备。这时候,增加ARM core的频率可以获取线性的程序性能提升。

3、bootloader中的程序执行过程描述

由于种种原因,我们的bootload中没有打开cache,没有启动MMU,而且bootloader中的代码在System RAM中运行。具体clock配置如下:

ARM clockBUS clockudelay的执行时间
260652.5ms
130652.5ms
65652.5ms
32.532.55ms

由于ARM core需要每次去system RAM中取指,虽然ARM core可以运行在260MHz下,但是由于BUS block限制在65MHz上,因此,大部分的时间,ARM core处于饥饿状态,这种状态下,什么流水线、什么out-of-order,什么分支预测都是浮云,性能的瓶颈来自上图中的A bus。因此,在260、130和65MHz下得到了相同的测试结果。

我们再来看看c代码版本的情况,使用objdump看看实际执行的代码是怎样的:

400202b0: e59f3028 ldr r3, [pc, #40] ; 400202e0 <.text+0x2e0>
400202b4: e5933000 ldr r3, [r3]
400202b8: e2432001 sub r2, r3, #1 ; 0x1
400202bc: e59f301c ldr r3, [pc, #28] ; 400202e0 <.text+0x2e0>
400202c0: e5832000 str r2, [r3]
400202c4: e59f3014 ldr r3, [pc, #20] ; 400202e0 <.text+0x2e0>
400202c8: e5933000 ldr r3, [r3]
400202cc: e3730001 cmn r3, #1 ; 0x1
400202d0: 1afffff6 bne 400202b0

汇编代码就2条指令,反复执行,c版本的看起来要复杂多了。为何c版本的delay函数没有出现和汇编版本的delay一样的测试结果呢?(TODO,我们留给大家思考吧)

PS:能完成这篇文档,我首先要感谢CCTV,MTV,各种TV,还有华南区linux kernel首席团队的LGR同学,多谢他的实验数据。

原创文章,转发请注明出处。蜗窝科技

标签:ARM性能

继续讨论

新讨论请用 GitHub 账号在下方发言——评论会保存在本仓库的 Discussions 里,与站点同寿; 再下方的「历史评论」是原站的只读存档。

评论(27 条,只读存档)

以下为原站的历史评论(只读存档);继续讨论请用上方的评论区。

  • tianhello

    赞一个! "2、在bootloader中测试"标号是不是写错了; “一个是c语音的版本”,c语言误写成c语音了。 PS:我没有强迫症。。。
    • linuxer

      @tianhello:多谢指正!已经修改
  • 动漫资讯 主页

    买了一个二手电脑,cpu不好
  • wowo

    骚年们,你们这一个260M的单核CPU,加上一个顶多130M的DDR,还整天调频来调频去的,汗!!!没法说你们了……哈哈。 PS:个人意见,在个人电脑、平板、智能手机等领域硬件指标太强悍了,例如1.6G 4核,720M DDR,才有动态调频的需求,因为确认可以省很多power,而且大部分场景用不着跑这么快。 至于其它的非主流产品,都给你省下来你能省多少啊?
    • tigger

      @wowo:跑分的时候一定要跑得快
      • wowo

        @tigger:哈哈,tigger不小心说实话了。
        • tigger

          @wowo:大家都知道啊,无论是手机厂商还是芯片厂商都心照不宣
  • perr

    站长对DRM有研究否? 最近,我一直为这个东西犯愁: 1.不知道怎么去搭建OpenGL库(mesa)的测试环境 2.找不到会mesa->libdrm->DRM(kernel)的华人/中文社区,发了封邮件,结果maintainer不理我 3.缺少drm的入门导引的资料(单纯代码来看,对我来说有些复杂) 我该肿么办呢?我想加入你们团队,自己摸索很无聊.
    • wowo

      @perr:perr,非常抱歉,恐怕不能帮到您。虽然我的工作内容是显示,但关于GPU的理解,还是比较浅,以至于无法很好的描述出来。 虽然后续有计划整理一下显示子系统的内容,但近期应该没有时间弄。 我能给您的建议就是,做这件事情之前,先厘清如下的问题: 1. 您的目的是什么?爱好?学习?工作?… 2. 您拥有哪些资源(硬件环境、软件环境、等等)?能不能把这些东西以block图的形式呈现出来? 3. 您的近期目标是什么?远期目标是什么?能不能把这些目标拆分? 4. 先不要关注细节,把东西run起来之后再说。因此着重点是模块之间的连接方式。 最后,如果您不介意,我可以在小站上给您开一个专题,记录您做这些事情的详细步骤,遇到问题的话,大家可以一起讨论,集思广益。先开动起来,把问题一个一个抛出来,总能解决,最怕的就是,不知道问题是什么。
      • RobinHsiang

        @wowo:请教华南区首席Linux PM\显示专家一个问题,我现在要通过网络远程获取LCD的显示情况,我主要是要确保LCD有在正常显示。客户端是运行安卓的ARM平台。 我现在能通过网络截图发送到服务器上供查看,但就算客户端的LCD不接上,我依然能从framebuffer里面读取数据。 针对这个问题,首席专家有建议没?
        • wowo

          @RobinHsiang:哈哈,什么首席不首席的,让您见笑了。我的观点是:除非你外加一个摄像头,实时监控,实时分析(人眼或者图像识别算法),才能确百分之百的万无一失。 当然,抛开“万无一失”的解法,我们可以换个思路: 怎样在LCD没有接上、损坏、以及其它异常的情况下,让客户端的软件先检测到?这可能需要根据实际情况,寻找具体的解决方案。
          • RobinHsiang

            @wowo:哈哈,我这几天都跟同事吹牛,说我最近经常跟南中国地区的首席linux专家请教讨论问题。 关于上面这个问题,我其实也硬件的软件的想了一些,我再想几天了再来跟你请教。 这就像风清扬教令狐冲武功,师傅指点了我得思考一下。不过我没令狐冲那资质,转的慢 ^_^
      • printk

        @wowo:wowo也是做显示的阿。
  • Adam_QSI

    好文章,希望能有对比较新的armv7 armv8架构的性能分析
  • buhui

    希望蜗蜗首席多发表些Linux内核方面的好文章,我们都是爱技术的人。
    • wowo

      @buhui:多谢鼓励,我们会尽力的,希望常来多交流。
  • femrat

    那个。。。cnt不是等于-1吗。。。。。。
    • linuxer

      @femrat:哪个地方cnt等于-1?能不能说的再清楚一些?
      • femrat

        @linuxer:不知道怎么描述位置。。抄一段原文… “情况依然,由于强大的编译器知道delay函数执行到最后cnt等于0,因此,在delay函数中就偷懒,直接给cnt赋值0”
        • linuxer

          @femrat:OK,知道你说的哪个地方了,这份文档的代码和思路都是另外一位同事做的,我是帮忙整理的文章。我觉得你说的是对的,不过,明天我还是用arm-linux-gcc验证一下
          • femrat

            @linuxer:感谢文章~另外我真不是强迫症QAQ
            • linuxer

              @femrat:我验证过了,你是对的。这当然不是强迫症,是你深厚的编程功力的体现,多谢拉。 另外,我review了这个错误发生的原因: while(--cnt);对应的汇编是 mov r2, #0 while(cnt--);对应的汇编是 mvn r2, #0 我猜测当初不认真,把mvn看成mov了,^_^
              • femrat

                @linuxer::-D 再次感谢文章~
  • 1

    博主使用的AD6900是否有资料可以分享,最近正在学习其开发,但由于芯片太老,网上找不到资料。
    • linuxer

      @1:抱歉,那些资料都是签了NDA的,不适合外传的。
      • 1

        @linuxer:原来是内部资料,难怪网上找不到呢,那方便请教一个关于其DSP MMR的问题吗?
  • 泥人

    资料不公开,是否可以问个问题?!呵呵 AD6900有片上BootROM吗? 谢谢。 文章时间有些久,不知还有响应吗?