PIC板全局变量与本地方法的C性能

时间:2012-02-07 14:50:33

标签: c performance global-variables pic pic18

所有

我的C函数每秒被调用很多次,因为它们是PIC18板上控制回路的一部分。这些函数的变量只需要方法范围,但我想知道如果有任何开销来不断分配这些变量与使用全局或至少更高范围的变量有什么关系。 (考虑到如果性能指示不使用方法本地变量,则输入一个结构来从更高的范围传递以避免全局变量使用)

这里有一些很好的主题可以涵盖这个主题,但是我还没有看到一个明确的答案,因为大多数传播最佳实践我同意并且会遵循,只要每微秒都不会有性能提升。

一个线程提到使用文件范围的静态变量替代全局变量,但我不禁想知道是否有必要。

每个人都在想什么?

3 个答案:

答案 0 :(得分:2)

访问局部变量需要执行*(SP + offset)之类的操作(其中SP是堆栈指针),而访问静态(包括全局变量)则需要*(address)之类的内容。

据我所知,PIC指令集的寻址模式非常有限。因此,访问全局的可能性更快,至少在第一次访问时更快。如果编译器将计算的地址保存在寄存器中,则后续访问可能相同。

正如@unwind在评论中所说的那样,你应该看看编译器输出和配置文件来确认。如果您已经证明在程序的运行时方面值得,那么我只会牺牲清晰度/可维护性。

答案 1 :(得分:1)

虽然我没有使用现有的每一个PIC编译器,但有两种样式。我使用的样式通过分析程序的调用图来静态分配所有局部变量。如果实际执行了每个可能的调用,本地人消耗的堆栈内存量将与静态分配所需的量相匹配,但需要注意几点(描述HiTech的PICC-18“标准”编译器的行为 - 其他可能会有所不同) )

  1. 通过在调用者的范围内定义局部变量存储,并将一个双字节指针传递给正在调用的函数,来处理变量函数。
  2. 对于间接函数指针的每个不同签名,编译器在调用图中生成“伪函数”;调用该签名函数的所有内容都调用伪函数,并且该伪函数使用具有其地址的签名调用每个函数。

在这种编译器风格中,对局部变量的连续访问与连续访问全局变量一样快。除了明确声明为“near”的全局变量和静态变量之外,其总数不得超过64-128个字节(因PIC的不同模型而异),每个模块的全局变量和静态变量与局部变量分开定位,需要银行转换指令来访问不同银行的东西。

我没有使用的一些编译器使用“增强指令集”选项。该选项吞噬了96个字节的“近”存储区(或所有存储区,小于96字节的PIC),并使用它来访问相对于FSR2寄存器的96个字节。如果它使用前16个或32个字节作为堆栈帧,这将是一个很好的概念。使用96字节意味着放弃所有“近”存储,这是一个非常严重的限制。尽管如此,使用此指令集的编译器可以访问堆栈上的局部变量,与全局变量一样快(如果不是更快)(不需要bank-switch)。我真的希望Microchip有一个选项,只为堆栈帧留出大约16个字节左右,留下一个有用数量的“普通银行”RAM,但是有些人对这种模式有好运。

答案 2 :(得分:0)

我认为这很大程度上取决于您使用的编译器。我不知道PIC,但我猜一些(所有?)PIC编译器将优化代码,以便尽可能将局部变量存储在CPU寄存器中。如果是这样,那么局部变量可能与全局变量一样快。

否则,如果在堆栈上分配局部变量,则全局访问速度可能会快一些(参见Oli的回答)。