ARM CPU性能实验

作者:linuxer 发布于:2015-4-9 18:13

一、前言

一般工程师的直觉是当提升了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)用示波器测量方波脉宽,记录实验数据。

实验结果如下:

clock udelay的执行时间
260 2.5ms
130 5.0ms
65 10ms
32.5 20ms

基本上,在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优化的方法,得到了下面的结果:

clock udelay的执行时间
260 2.610ms
130 3.720ms
65 4.630ms
32.5 9.242ms

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

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

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

clock udelay的执行时间
260 2.5ms
130 2.5ms
65 2.5ms
32.5 5ms

呵呵,结果多么的神奇。

 

三、分析

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 clock BUS clock udelay的执行时间
260 65 2.5ms
130 65 2.5ms
65 65 2.5ms
32.5 32.5 5ms

由于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性能

评论:

泥人
2018-07-16 10:50
资料不公开,是否可以问个问题?!呵呵
AD6900有片上BootROM吗?

谢谢。
文章时间有些久,不知还有响应吗?
1
2018-01-11 09:01
博主使用的AD6900是否有资料可以分享,最近正在学习其开发,但由于芯片太老,网上找不到资料。
linuxer
2018-01-11 22:00
@1:抱歉,那些资料都是签了NDA的,不适合外传的。
1
2018-01-12 11:38
@linuxer:原来是内部资料,难怪网上找不到呢,那方便请教一个关于其DSP MMR的问题吗?
femrat
2015-09-17 12:46
那个。。。cnt不是等于-1吗。。。。。。
linuxer
2015-09-17 23:17
@femrat:哪个地方cnt等于-1?能不能说的再清楚一些?
femrat
2015-09-17 23:20
@linuxer:不知道怎么描述位置。。抄一段原文… “情况依然,由于强大的编译器知道delay函数执行到最后cnt等于0,因此,在delay函数中就偷懒,直接给cnt赋值0”
linuxer
2015-09-17 23:28
@femrat:OK,知道你说的哪个地方了,这份文档的代码和思路都是另外一位同事做的,我是帮忙整理的文章。我觉得你说的是对的,不过,明天我还是用arm-linux-gcc验证一下
femrat
2015-09-18 02:35
@linuxer:感谢文章~另外我真不是强迫症QAQ
linuxer
2015-09-18 12:23
@femrat:我验证过了,你是对的。这当然不是强迫症,是你深厚的编程功力的体现,多谢拉。

另外,我review了这个错误发生的原因:
while(--cnt);对应的汇编是 mov     r2, #0
while(cnt--);对应的汇编是 mvn     r2, #0

我猜测当初不认真,把mvn看成mov了,^_^
femrat
2015-09-18 13:26
@linuxer::-D  再次感谢文章~
buhui
2015-08-08 14:33
希望蜗蜗首席多发表些Linux内核方面的好文章,我们都是爱技术的人。
wowo
2015-08-09 17:57
@buhui:多谢鼓励,我们会尽力的,希望常来多交流。
Adam_QSI
2015-05-04 14:14
好文章,希望能有对比较新的armv7 armv8架构的性能分析
perr
2015-04-14 19:48
站长对DRM有研究否?
最近,我一直为这个东西犯愁:
1.不知道怎么去搭建OpenGL库(mesa)的测试环境
2.找不到会mesa->libdrm->DRM(kernel)的华人/中文社区,发了封邮件,结果maintainer不理我
3.缺少drm的入门导引的资料(单纯代码来看,对我来说有些复杂)
我该肿么办呢?我想加入你们团队,自己摸索很无聊.
wowo
2015-04-14 21:19
@perr:perr,非常抱歉,恐怕不能帮到您。虽然我的工作内容是显示,但关于GPU的理解,还是比较浅,以至于无法很好的描述出来。
虽然后续有计划整理一下显示子系统的内容,但近期应该没有时间弄。
我能给您的建议就是,做这件事情之前,先厘清如下的问题:
1. 您的目的是什么?爱好?学习?工作?…
2. 您拥有哪些资源(硬件环境、软件环境、等等)?能不能把这些东西以block图的形式呈现出来?
3. 您的近期目标是什么?远期目标是什么?能不能把这些目标拆分?
4. 先不要关注细节,把东西run起来之后再说。因此着重点是模块之间的连接方式。
最后,如果您不介意,我可以在小站上给您开一个专题,记录您做这些事情的详细步骤,遇到问题的话,大家可以一起讨论,集思广益。先开动起来,把问题一个一个抛出来,总能解决,最怕的就是,不知道问题是什么。
RobinHsiang
2015-04-23 16:14
@wowo:请教华南区首席Linux PM\显示专家一个问题,我现在要通过网络远程获取LCD的显示情况,我主要是要确保LCD有在正常显示。客户端是运行安卓的ARM平台。
我现在能通过网络截图发送到服务器上供查看,但就算客户端的LCD不接上,我依然能从framebuffer里面读取数据。
针对这个问题,首席专家有建议没?
wowo
2015-04-23 17:15
@RobinHsiang:哈哈,什么首席不首席的,让您见笑了。我的观点是:除非你外加一个摄像头,实时监控,实时分析(人眼或者图像识别算法),才能确百分之百的万无一失。
当然,抛开“万无一失”的解法,我们可以换个思路:
怎样在LCD没有接上、损坏、以及其它异常的情况下,让客户端的软件先检测到?这可能需要根据实际情况,寻找具体的解决方案。
RobinHsiang
2015-04-23 23:08
@wowo:哈哈,我这几天都跟同事吹牛,说我最近经常跟南中国地区的首席linux专家请教讨论问题。
关于上面这个问题,我其实也硬件的软件的想了一些,我再想几天了再来跟你请教。
这就像风清扬教令狐冲武功,师傅指点了我得思考一下。不过我没令狐冲那资质,转的慢 ^_^
printk
2015-04-23 17:32
@wowo:wowo也是做显示的阿。
wowo
2015-04-11 11:45
骚年们,你们这一个260M的单核CPU,加上一个顶多130M的DDR,还整天调频来调频去的,汗!!!没法说你们了……哈哈。
PS:个人意见,在个人电脑、平板、智能手机等领域硬件指标太强悍了,例如1.6G 4核,720M DDR,才有动态调频的需求,因为确认可以省很多power,而且大部分场景用不着跑这么快。
至于其它的非主流产品,都给你省下来你能省多少啊?
tigger
2015-04-13 16:08
@wowo:跑分的时候一定要跑得快
wowo
2015-04-13 16:58
@tigger:哈哈,tigger不小心说实话了。
tigger
2015-04-14 09:47
@wowo:大家都知道啊,无论是手机厂商还是芯片厂商都心照不宣
动漫资讯
2015-04-10 23:07
买了一个二手电脑,cpu不好
tianhello
2015-04-09 18:40
赞一个!
"2、在bootloader中测试"标号是不是写错了;
“一个是c语音的版本”,c语言误写成c语音了。
PS:我没有强迫症。。。
linuxer
2015-04-10 04:43
@tianhello:多谢指正!已经修改

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog