STM32 gcc优化产生不同的结果

STM32 gcc optimization produces different result

我正在尝试使用 STM32F4(SW4STM32 中的 gcc IDE)将 RGB 缓冲区解码为适合 LED RGB 矩阵的行。 下面的代码在设置编译器优化 -O0 时完美运行。

代码在使用-O1 优化编译时产生不同的结果。 (还有-O2、-O3)。 当使用 -O1.

将 (attribute((packed)) 添加到结构 color_t 定义时,代码也会产生不同的结果

优化设置只针对这个.c文件,其他文件还是-O0。

有人能看出优化更改代码的原因 logic/behavior 吗?

uint8_t badr[24576] = { 0xff , 0x2a, .... };

struct s_color_t
{
    uint8_t r;
    uint8_t g;
    uint8_t b;
} ;
//__attribute__((packed))

typedef struct s_color_t color_t;

#define WIDTH       128
#define HEIGHT      64
#define COLOR_SIZE  sizeof(color_t)

#define R0_POS      0x01
#define G0_POS      0x02
#define B0_POS      0x04
#define R1_POS      0x08
#define G1_POS      0x10
#define B1_POS      0x20

#define enc_color(c, s, r)  (c & s)? r : 0

color_t dispBuf[ WIDTH * HEIGHT];
uint8_t dispLine[WIDTH];

void fillBuf()
{
    uint8_t *dbuf = (uint8_t *) dispBuf;
    memcpy(dbuf, badr, WIDTH * HEIGHT * COLOR_SIZE);
}

void enc_row(uint8_t slice, uint16_t row, uint8_t *rBuf)
{
    uint8_t reg;

    color_t *upPtr = dispBuf + row * WIDTH * COLOR_SIZE;
    color_t *dnPtr = dispBuf + (row + (HEIGHT / 2)) * WIDTH * COLOR_SIZE;
    uint8_t *destPtr = rBuf;

    uint8_t sn = (1 << slice);
    for (int i=0; i < WIDTH; i++) {
        reg = 0;
        reg |= enc_color((*upPtr).r, sn, R0_POS);
        reg |= enc_color((*upPtr).g, sn, G0_POS);
        reg |= enc_color((*upPtr).b, sn, B0_POS);
        reg |= enc_color((*dnPtr).r, sn, R1_POS);
        reg |= enc_color((*dnPtr).g, sn, G1_POS);
        reg |= enc_color((*dnPtr).b, sn, B1_POS);

        *destPtr = reg;
        upPtr ++;
        dnPtr ++;
        destPtr ++;
    }
}

void do_func() 
{
    uint8_t *ptrLine = dispLine;

    fillBuf();
    for (int s=0; s < 8; s++) {
        for (int i=0; i< (HEIGHT/2); i++) {
            enc_row(s, i, ptrLine);
            printf("line %3i ", i);

            for(int c=0; c<WIDTH; c++) {
                printf("%02X, ", ptrLine[c] & 0xFF);
            }
            printf("\r\n");
        }
    }
}

谢谢Zan Lynx。 事实上,如果一个人打算稍后使用优化,他应该放置检查点来验证代码产生与优化相同的结果。

上面的错误结果是由指针计算引起的。我用 :

替换了上面的两个语句
upPtr = &dispBuf[row * WIDTH];
dnPtr = &dispBuf[(row + (HEIGHT / 2)) * WIDTH];

在调试过程中(打开优化),删除了几个函数(即操作由编译器完成。)

说到嵌入式,到其他设备的接口信号也可能改变速度。您可能会超频或缩短脉冲。

使用 -O1 代码执行时间减少了 60%。