局部变量和静态结构之间的执行时间不同

时间:2014-06-29 14:56:24

标签: structure avr

我在AVR的微控制器上写了一个程序。它应该检查实际温度并在7段显示器上显示。这就是我所遇到的问题:我制作了一个所有变量都参考温度(温度,指针位置,符号和单位)的结构,并看到了例如执行时间。除非使用正常局部变量,否则除以10或mod 10要长得多。我不知道为什么。我使用的是Atmel Studio 6.2。

struct dane
{
    int32_t temperature;
    int8_t pointer;
    int8_t sign;
    int8_t unit;
};
//************************************
//inside function of timer interrupt
static struct dane present;

//*****************************
//tested operations:
present.temperature % 10;    //execution time: ~380 processor's cycles, on normal local variable ~4 cycles.
present.temperature /= 10;    //execution time: ~611 cycles

我给你这个功能,我使用它和一些汇编代码。

ISR(TIMER0_OVF_vect)
{
    static int8_t i = 4;
    static struct dane present;

    if(i == 4 && (TCCR0 & (1 << CS01)))
    {
        i = 0;
        present = current;
        if(present.temperature < 0)
            present.temperature = -present.temperature;         
    }

    if((TCCR0 & ((1 << CS00) | (1 << CS02))) && i != 0)
    {
        i = 0;
    }
    if(present.unit == current.unit) //time between here and fist instruction in function print equals about 300 cycles.
    {
        print((i * present.sign == 3 && present_temperature % 10 == 0) ? 16 : present_temperature % 10, displays[i], i == present.pointer);
    }
    else
    {
        print(current.unit, displays[i],0);
        if(i == 4)
        {
            i = 3;
            TCCR0 = (1 << CS01);
            present.unit = current.unit;
        }
    }

    present.temperature /= 10;
    i++;
}

最后一条指令前的汇编代码:

present.temperature /= 10;
0000021F  LDI R28,0x7D      Load immediate
00000220  LDI R29,0x00      Load immediate
00000221  LDD R22,Y+0       Load indirect with displacement
00000222  LDD R23,Y+1       Load indirect with displacement
00000223  LDD R24,Y+2       Load indirect with displacement
00000224  LDD R25,Y+3       Load indirect with displacement
00000225  LDI R18,0x0A      Load immediate
00000226  LDI R19,0x00      Load immediate
00000227  LDI R20,0x00      Load immediate
00000228  LDI R21,0x00      Load immediate
00000229  RCALL PC+0x01AC       Relative call subroutine
0000022A  STD Y+0,R18       Store indirect with displacement
0000022B  STD Y+1,R19       Store indirect with displacement
0000022C  STD Y+2,R20       Store indirect with displacement
0000022D  STD Y+3,R21       Store indirect with displacement

我不能将int16_t用于温度,因为我在内部使用相同的结构来转换传感器的温度,当我乘以适当数量的10时,它更容易操作带小数部分的数字。

1 个答案:

答案 0 :(得分:0)

你的时间一定有问题:

present.temperature % 10;    //execution time: ~380 processor's cycles, on normal local variable ~4 cycles.
present.temperature /= 10;    //execution time: ~611 cycles

对于32位值的模10操作永远不会在AVR的4个时钟周期内发生。 380个周期听起来很多,但对于32:32的分组操作更为现实。我担心即使AVR上的整数除法也会花很多时间用长整数。

对模块静态变量的操作需要更长的时间是很自然的,因为它们必须被取出并存储在RAM中。与寄存器变量相比,每个字节可能需要10个额外的时钟周期(局部变量通常在寄存器中。结构中的变量在这种情况下不应该改变时序(指向结构的指针可能有一个效果)。

了解正在发生的事情的唯一真正方法是查看编译器在每种情况下生成的汇编代码。

而且,请在您的问题中包含两个案例的最小但完整的示例。然后更容易看出是否有明显的错误。


如果您对提高代码速度感兴趣,建议您尝试使用int16_t作为温度。您的温度测量动态范围几乎不超过12位(例如,对于-100°C .. + 300°C之间的温度,这将是0.1°C。)因此16位整数应该足够了。