如何在资源较少的设备上测试算法性能?

时间:2014-06-25 07:05:11

标签: performance algorithm testing arduino attiny

我有兴趣使用atmel avr控制器从LIN总线读取数据。不幸的是,这种总线上的消息没有开始或结束指示,只有合理的解决方案似乎是强力解析。来自总线的可用数据被加载到循环缓冲区中,而暴力方法在缓冲区中查找有效消息。

使用64字节缓冲区和20MHZ attiny,如何测试代码的性能以查看是否可能发生缓冲区溢出?补充:我担心的是算法运行缓慢,从而缓冲更多数据。

有点蛮力算法。假设缓冲区中的第二个元素是消息大小。例如,如果假设长度为22,则前21个字节进行异或,并在缓冲区中对第22个字节进行测试。如果校验和通过,代码检查第一个(SRC)和第三个(DST)字节是否应该是它们。

2 个答案:

答案 0 :(得分:1)

AVR是性能分析最简单的微控制器之一,因为它是一台RISC机器,具有简单的指令集和每条指令的众所周知的指令执行时间。

所以,基本的程序是你采取装配,并开始计算不同的场景。基本寄存器操作需要一个时钟周期,通常分支两个周期,存储器访问三个周期。 XORing周期每个字节可能需要5-10个周期,因此它相对便宜。如何掌握汇编代码取决于编译器,但所有编译器都倾向于以合理的清晰形式给出最终结果。

通常在没有看到算法并且知道任何关于时序要求的情况下,很难对这类问题给出明确的答案。但是,由于LIN总线速度限制为20 kbit / s,因此每个字节将有大约10 000个时钟周期。这几乎适用于任何事情。


更难的问题是如何处理依赖于时序的LIN帧。这不是一个很好的习惯,因为它需要一些额外的努力来从微控制器。 (使用第9位到底有什么问题?)

LIN帧由

组成
  • 休息(至少13位)
  • synch delimiter(0x55)
  • 消息ID(8位)
  • 消息(0..8 x 8位)
  • 校验和(8位)

至少有四种可能的起伏方法:

  1. (您的apporach。)从所有可能的起始位置开始,并尝试确定校验和消息的位置。一旦你同步,这是不需要的。 (很容易但以1/256的概率返回幽灵信息。请记住丢弃同步字段。)

  2. 使用内部UART并查找同步字段;试着弄清楚分隔符后的数据是否有意义。 (这比上述错误概率低,但要求同步定界符没有毛刺,因此可能会错过消息。)

  3. 寻找休息时间。最简单的方法是为所有到达的字节加时间戳。很可能不需要以任何方式缓冲输入数据,因为数据速率非常低(最大2000字节/秒)。名义上,帧的最后一个字符的结尾与下一帧的第一个字符的开始之间的距离至少为13位。当接收字符需要10比特时,接收前一消息中的最后一个字符的结尾与下一个消息的第一个字符的结尾之间的延迟名义上至少为23比特。为了允许对比特定时进行一些容限,可以将限制设置为,例如, 17位。如果“字符接收”中断之间的时间间隔超过此限制,则字符属于不同的帧。一旦检测到中断,您可以开始收集新消息。 (这几乎符合官方规范。)

  4. 一点一点地自己动手。如果从站和主站之间没有良好的同步,则必须使用此方法确定主时钟。实现不是很简单,但是一个例子是:http://www.atmel.com/images/doc1637.pdf(我并不认为一个是万无一失的,而是相当简单。)

  5. 我会选择#3。为传入数据创建一个中断,每当数据到来时,将当前时间戳(您需要一个计数器)与前一个中断的时间戳进行比较。如果字符间时间太长,则启动新消息,否则附加到旧消息。然后,您可能需要对消息进行双缓冲(您正在收集的消息,另一个正在分析的消息)以避免很长的中断例程。

    实际的实现取决于代码的其他结构。这不应该花费太多时间。

    如果你不能确保你的时钟与moster时钟同步(+ - 4%),那么你将不得不看#4,这可能更有启发性,但相当繁琐。

答案 1 :(得分:0)

你的基本问题是(我认为):

  

如何测试代码的性能以查看是否可能发生缓冲区溢出?

在算法开始时将引脚设置为高电平,在结束时将其设置为低电平。在示波器上观察它(我假设你有其中之一 - 没有它就很难进行嵌入式开发。)你将能够测量算法所需的最大时间,并且还可以了解可变性。