硬汉嵌入式论坛

 找回密码
 立即注册
查看: 747|回复: 10
收起左侧

[MDK] MDK AC6的LTO优化有时候会将uint8_t buf[128]定义存到内部Flash

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118335
QQ
发表于 2025-9-1 11:47:07 | 显示全部楼层 |阅读模式
【问题由来】

一位V7板子客户发现了个这种问题,研究下了,发现是开启LTD优化导致的。

MDK AC6会这样,而MDK AC5没有LTO配置项,所以没有这个问题

【测试代码】

[C] 纯文本查看 复制代码
uint8_t buf[128] = {
    0x30, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
    0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
    0x33, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
    0x31, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
    0x35, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
    0x31, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
    0x37, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
    0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
    0x39, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
    0x39, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
    0x39, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
    0x39, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x38, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
    0x37, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
    0x36, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
    0x35, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3
};

        for (int i=0; i<128; i++)
        if(buf[i] > 100) {bsp_LedToggle(1);}


【MDK配置】

下载 (3).png

看map文件,直接别分配到rodata只读数据了

下载 (4).png

【简单分析】

如果LTO通过全局分析发现数组 buf  在程序运行过程中从未被修改(即它是实质上的常量),它会进行一项关键优化:
1、不再在RAM中为其分配空间,也省去了启动时从Flash拷贝数据到RAM的步骤。
2、相反,编译器会直接让所有访问数组 a 的代码去直接读取Flash中存储初始值的地址。

这样做的好处是:
1、节省RAM空间:数组完全不占用RAM。
2、节省启动时间:无需执行拷贝操作。
回复

使用道具 举报

5

主题

175

回帖

190

积分

初级会员

积分
190
发表于 2025-9-2 09:13:46 | 显示全部楼层
开LTD 优化会导致DMA执行异常,不会也是把内存内的DMA数据也搬到flash了?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118335
QQ
 楼主| 发表于 2025-9-2 10:22:32 | 显示全部楼层
2859932063 发表于 2025-9-2 09:13
开LTD 优化会导致DMA执行异常,不会也是把内存内的DMA数据也搬到flash了?

这个有必要深入看下了,LTO优化有时候比较激进。
回复

使用道具 举报

2

主题

90

回帖

96

积分

初级会员

积分
96
发表于 2025-9-2 10:47:46 | 显示全部楼层
[C] 纯文本查看 复制代码
for (int i=0; i<128; i++)
        if(buf > 100) {bsp_LedToggle(1);}



这段代码有问题,应该是


[C] 纯文本查看 复制代码
for (int i=0; i<128; i++)
        if(buf[i] > 100) {bsp_LedToggle(1);}

回复

使用道具 举报

39

主题

1519

回帖

1641

积分

至尊会员

积分
1641
发表于 2025-9-2 13:22:56 | 显示全部楼层
我现在H743项目代码考虑性能,全部-Ofast+LTO,性能提升很明显
回复

使用道具 举报

219

主题

1114

回帖

1781

积分

至尊会员

More we do, more we can do.

积分
1781
发表于 2025-9-2 13:35:32 | 显示全部楼层
看标题就想,估计是把变量优化成了常量。
回复

使用道具 举报

5

主题

175

回帖

190

积分

初级会员

积分
190
发表于 2025-9-2 14:08:48 | 显示全部楼层
sanit 发表于 2025-9-2 13:22
我现在H743项目代码考虑性能,全部-Ofast+LTO,性能提升很明显

DMA正常吗? 我只是单纯测试的时候 DMA有些问题
回复

使用道具 举报

104

主题

585

回帖

912

积分

金牌会员

积分
912
QQ
发表于 2025-9-2 17:01:12 | 显示全部楼层
本帖最后由 会飞的猪_2020 于 2025-9-4 15:55 编辑

我用ac6 -oz优化的时候,发现它有时候会把两个变量放到一个内存里。。导致出问题。

类似于这样的伪代码:
[C] 纯文本查看 复制代码
uint32_t var;

void function1() {
    var = get_var();
    ....
}


它会把这个全局变量var和别的全局变量的内存用同一块。

估计是为了节省空间,做的操作。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118335
QQ
 楼主| 发表于 2025-9-3 09:22:32 | 显示全部楼层
CoderXMan 发表于 2025-9-2 10:47
这段代码有问题,应该 ...

是的,是这样的,我原来定义是buf_test,方便分享我把这个改成buf了,后面的序号给删掉了。

楼主位已经修改
回复

使用道具 举报

89

主题

566

回帖

833

积分

金牌会员

积分
833
发表于 2025-9-4 06:20:34 来自手机 | 显示全部楼层
如果是指针访问写呢?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118335
QQ
 楼主| 发表于 2025-9-5 09:44:15 | 显示全部楼层
tangqianfeng 发表于 2025-9-4 06:20
如果是指针访问写呢?

这个得测试下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-9-26 19:29 , Processed in 0.061726 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表