对于Cortex M0 M3 M4 的我知道可以在其《Technical Reference Manual 》> Programmers Model > Instruction set summary 里面查看
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0432c/CHDCICDF.html
但是到了M7, 他告诉我去ARM-V7-M的手册中找
“The processor implements the ARMv7-M instruction set and features provided by the ARMv7E-M architecture profile. For more information about the ARMv7-M instructions, see the ARM®v7-M Architecture Reference Manual.” -----《ARM Cortex-M7 Processor Technical Reference Manual》Programmers Model > Instruction set summary > Binary compatibility with other Cortex processors
但是在 V7-M 手册里,也没有找到具体的指令执行周期。请问应该去哪里找呢
您好,真不好意思又要叨扰了。这几天看了DWT,确实很好用。只是有个问题是DWT中除了CYCCNT外的counter,都只有8bit的register。所以如果一段程序稍长一点的话就溢出了,既然CPI是统计的话,一段一端的测程序好像会不太准的样子。这个overflow,v7-M 手册里说会触发counter overflow event,但是我没找到怎么收集这个event,是需要设置一个中断触发吗? 因为这个,我最后还是选择keil debug中的trace,用ITM来trace 这些event,因为里面可以累加counter的值,也能读到overflow事件。只是跟DWT printf出来的,有点不太一样。
另外我看keil debug的话,时钟周期的测量也是通过coresight来trace的,如果一段程序稍长一些的(不是by instruction),keil里显示的数据跟DWT CYCCNT出来的是一样的。
非常感谢。
DWT本身就是个低成本的东西,设计目的就是应对局部。大程序(运行时间长的)要用高精度的示波器(或者逻辑分析仪)配合IO口翻转来测量时间(在测量开始的时候拉低电平,在测量结束的时候拉高电平,最终计算的时候,由拉低电平引入的误差基本忽略不计)——我还是那句话,不要相信Debug,一切都要实测。
DWT也算是debug的一种?用示波器测io反转的话,只能获得该段程序运行的运行事件,具体的指令数量看来只能动手数了。非常感激大神的耐心解答。
DWT严格来说只是一个系统的辅助外设,Debug可以访问而已。CYCCNT也不过就是帮你记录一个时间而已,指令还是要你自己去数的。就是因为这么麻烦,通常,除了研究流水线的专业人士,普通人也就是只关注实系统的实际运行性能而已。而实际运行性能和CPI其实关系不大,因为这里存在一个间接的关系:
系统性能 = 完成指定的功能/应用/运算 所花费的时间
这里,完成指定功能的程序 又要经过编译器才能生成机器码,而生成怎样的机器码,即受到编译器的限制,又受到指令集的限制。在这种情况下,CPI好不代表最终系统性能好,因为你可能完成一个功能要很多很多指令,但是每个指令CPI都很不错,最终,完成功能所用的总时间却很长。
所以,评估性能,从应用层面,往往不看底层的CPI,看了没啥用啊,太间接了。所以,直接用Benchmark去跑分更实用。除非你是做热点代码优化的,否则CPI对你意义真的很有限。
就是怕你钻牛角尖,最后做了无用功才给你说这么多的。要有Big Picture,普通人关心CPI真是屁用不顶的。
是这样的,我老师让我在ARM上跑机器学习算法。对于这个机器学习算法性能的评估需要精确到clock cycle。arm不同的核,影响因素可能众多,我就想得到一个有参考价值的时间数值,比如机器周期,这样在往其他核移植的时候比较好评估,比如可以乘以一个该核CPI还有频率就能得到大致的时间范围。现在我在对这个模型做优化,想看看什么部分对时间影响比较严重。算法的每个部分消耗多大,store和load影响多大。需要store\load多一点来减小memory数量比较好,还是加点memory减少点store\load比较好这样的。
这种算法性能评估就是典型的应用,不建议用CPI。而普通benchemark生成最终跑分的方法非常具有参考价值。简单说,就是统计跑一个算法用了多少时间,然后normalized到某个频率下的数值就是结果。比如,你用100MHz频率跑某个算法用了时间T,那么T/100 (Normalized to 1MHz)的结果就是性能的跑分。
前面说过,由于测不准的问题,你现在就算跑出一个CPI,我跟你很负责任的讲,换个编译器,换个编译器版本,换个编译选项,甚至改了几行无关紧要的代码,最后CPI都会变的。这里水很深。不然Benchmark也不会有人说水很深了。
这样啊,感觉不只是水很深的样子了,简直是毫不可测。loop的时候,branch predicter 是不是也有影响,branch predicter里面是不是有pid什么的算法