测量应用绩效改进的三种技术
扫描二维码
随时随地手机看文章
有关开发人员如何通过在RAM中执行时间敏感功能而不是从Flash中执行时间敏感功能来加快其应用程序代码的文章。您可能想知道是否要进行这样的调整,表现会发生什么变化?答案会根据微控制器的制造技术而有所不同,但是开发人员可以使用三种技术来衡量其应用程序或功能性能:
· 切换一个I/O PIN
· 设置计时器
· 使用ITM
让我们详细检查这些技术。
技术#1 - 切换一个I/O PIN
本书中的第一个也是最古老的技巧是使用备用的I/O PIN并在执行功能之前和之后对其进行切换。我们想两次进行此测量。首先,当功能仍在Flash执行时。其次,一旦我们移动了从RAM执行的功能,或者当我们进行了任何优化时,我们感兴趣的是。执行此操作非常简单,可以通过直接操纵位或通过硬件抽象层来完成列表1和列表2中的硬件抽象层进行完成。
porta&= 〜0x1;
myTestFunction();
porta | = 0x1;
清单1 - 直接访问端口寄存器以在执行功能时切换引脚。
dio_channelwrite(porta_0,low);
myTestFunction();
dio_channelwrite(porta_0,High);
列表2 - 间接访问端口寄存器以通过硬件抽象层执行功能时切换引脚。
技术#2 - 设置计时器
可用于测量时间的第二种技术是设置硬件计时器。有两种方法可以使用硬件计时器。首先,它可以用作单个射击计时器,在调用函数之前,该计时器立即启动。其次,可以将计时器设置为不断运行,并在函数调用之前和之后阅读。在这种情况下,开发人员将不得不添加额外的代码来计算计时器寄存器中开始和停止值之间的差异。要注意的一个重要提示是,您需要确保计时器以足够高的分辨率滴答以捕获差异。例如,计时器的1毫秒可能太大。 10微秒的步骤可能是一个不错的起点。列表3和列表4显示了一些伪代码,介绍了如何使用计时器来测量时间差异。
timer_start(timer_1); //开始清除计时器寄存器计数
myTestFunction();
timer_stop(timer_1);
timerCount = timer_read(timer_1);
清单3 - 使用驱动程序API启动并停止计时器以直接测量函数执行时间的时间。
countstart = timer_read(timer_1);
myTestFunction();
countstop = timer_read(timer_1);
ElapSedTime =(Countstop - Countstart) * TimerTickunit;
清单4 - 使用运行计时器使用运行计时器来测量函数需要执行多长时间。必须注意确保计时器读取为原子。
技术#3 - 使用ITM
可以使用但取决于可用的MicroController架构和硬件的第三种技术是使用指令Trace Microcell(ITM)。 ITM通常在ARM Cortex-M处理器上可用,旨在允许开发人员将跟踪信息快速传递给调试器,而无需大量的软件开销:硬件可以进行繁重。该软件真的很简单。首先,开发人员需要确保它们包含其微控制器的核心标头文件。例如,如果我正在使用Cortex-M4,则将包括core_cm4.h。标题文件包含一个重要功能,用于访问称为ITM_SENDCHAR的ITM。我们可以使用itm_sendchar在执行函数之前和之后通过ITM发送字符,如列表5所示。
itm_sendchar('a');
myTestFunction();
itm_sendchar('a');
清单5 - ARM函数ITM_Sendchar可用于在函数执行之前和之后通过ITM发送数据字节,以获取有关该函数的定时信息。
每个ITM数据包不仅包含字符,还包含数据包周期数。函数之前和之后的循环计数之间的差异可用于获取经过多少个CPU周期。这可以在图1中看到,其中ITM端口1用于显示关注功能的开始,而ITM端口2用于显示感兴趣的功能的结束。在这种情况下,我们可以看到16个周期的差异(在此示例中我的测试功能很重要)。
示例屏幕快照,显示用于监视事件之间的周期数的ITM。在此屏幕截图中,ITM端口1被用于显示函数的开始,然后使用ITM端口2显示函数的末尾。
结论
在这篇文章中,我们研究了开发人员可以用来衡量其软件性能提高的三种技术。这些技术都是在编写基于金属或基于RTOS的应用程序的工作。每种技术确实都要求开发人员仪器的软件,因此请记住,可能会在测量中添加其他开销。虽然,选择一个单一的技术将提供一个苹果对苹果的比较。