OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12008|回复: 15

uV4如何在优化级别0的情况下,使得for循环实现在优化级别3时的运行速度?

[复制链接]

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
发表于 2015-12-22 20:47:23 | 显示全部楼层 |阅读模式
5金钱
以下是uV4的优化级别设置:




以下是所要运行的程序(for循环实现从后面地址中提取数据送给shuzhu1[]):



for()循环的执行速度,在优化级别为0的情况下是在优化级别为3的情况下的10/14,
虽然在优化3的情况下执行速度快,但是debug效果很差,程序会乱跑,不能用优化3
而优化0情况下,虽然debug正常,但是执行速度比较慢
所以我就想是不是可以在优化级别0的情况下,通过某种方法使得for循环执行速度达到优化3情况下的速度(别的程序不用快,只要for循环快就行)
现在有两个想法:
1,for循环部分直接用汇编编写,在优化0的情况下把for循环替换成优化3下的for的反汇编指令
2,对现有的for循环优化,例如用指针什么的,或者用别的更快的循环方法代替for循环(具体还不知怎么办)


以下为优化0情况下和优化3情况下,for循环反汇编

优化0(黑色部分):



优化3(黑色部分)




哪位大神知道的,请给点意见,谢谢!

最佳答案

查看完整内容[请看2#楼]

这样赋值会导致每次循环都进行一次读FLASH操作(0x60010000数值保存在FLASH) 建议: uint32_t  temp = 0x60010000; while(1) {     for(i=0; i<300; i++)     {         shuzu1 = *(volatile uint8_t*)temp;     } }
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12208
金钱
12208
注册时间
2015-11-5
在线时间
2116 小时
发表于 2015-12-22 20:47:24 | 显示全部楼层


这样赋值会导致每次循环都进行一次读FLASH操作(0x60010000数值保存在FLASH)

建议:

uint32_t  temp = 0x60010000;

while(1)
{
    for(i=0; i<300; i++)
    {
        shuzu1 = *(volatile uint8_t*)temp;
    }
}
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12208
金钱
12208
注册时间
2015-11-5
在线时间
2116 小时
发表于 2015-12-22 20:47:24 | 显示全部楼层
回复【5楼】等待烟花美:
---------------------------------
MDK的编译器还真没研究过,不过你提出的“for循环部分直接用汇编编写”其实比较好,并且比较稳妥,建议就用汇编代替for循环部分好了
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

14

主题

1592

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2622
金钱
2622
注册时间
2014-7-17
在线时间
350 小时
发表于 2015-12-22 21:40:12 | 显示全部楼层
帮顶。。。。
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-23 16:19:11 | 显示全部楼层
回复【2楼】FantaSy_:
---------------------------------
谢谢
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-23 16:33:18 | 显示全部楼层
回复【3楼】FreeRTOS:
---------------------------------
非常感谢,这样改确实有用。按照你那样改,在优化0的情况下,与之前相比确实反汇编少了第一句话 LDR r0,[pc,#20],但是与优化3情况下相比,还是不太一样,想问一下怎么修改才能使得反汇编达到优化3那样的6条语句?
或者您知不知道uv4 MDK有没有类似#pragma OPTIMIZE(3)这样的指令,能够使得在优化设置为0的情况下,只对for循环进行优化3?
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-23 19:42:28 | 显示全部楼层
回复【6楼】FreeRTOS:
---------------------------------
好的,非常感谢
回复

使用道具 举报

7

主题

75

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2012-12-30
在线时间
41 小时
发表于 2015-12-23 20:37:05 | 显示全部楼层
在STM32F7的库里看到有这样的语句
#if defined   (__CC_ARM) /*!< ARM Compiler */
#pragma O0
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma GCC optimize ("O0")
#endif /* __CC_ARM */
整个工程设置的是O3的优化等级,不过这貌似是对一整个函数进行优化,不知道能不能对函数内的某一部分优化。实在想提高速度的话就用DMA呗
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12208
金钱
12208
注册时间
2015-11-5
在线时间
2116 小时
发表于 2015-12-24 17:05:18 | 显示全部楼层
回复【7楼】等待烟花美:
---------------------------------
楼主,想请教你个问题,MDK的优化级别2和优化级别3编译代码后,代码量相差比较少,想问下你如果我不考虑这么点代码量差别时,那么选用优化级别2好呢还是用优化级别3好?
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-24 21:58:02 | 显示全部楼层
回复【8楼】xijiele:
---------------------------------
不知道F4库里有没有带,我试试看把for循环写成子函数行不行,我在网上也看到对keil的局部优化的指令
#pragma -Otime

int SmallAndUsedOften()

{/* Do something here. */

}

#pragma –Ospace

int BigAndSeldomUsed()

{/* Do something here. */

}

#pragma –O1 /* Selection between –O1, –O2, –O3 */

int OpExampleUsed()

{/* Do something here. */

}


谢谢哈!
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-24 22:06:22 | 显示全部楼层
回复【9楼】FreeRTOS:
---------------------------------
我程序感觉优化2和优化3debug的时候,乱跳的效果一样。
一般好像基本用优化0,不咋的会出问题。用优化2,3的话,我老是出问题,程序乱跑,有人说优化2,3不出出问题,问题出在程序不够规范上。
优化3好像是在时间和空间上优化,可能涉及到某些程序时,优化3会比优化2优化的更多一点。
不过如果不是必要,还是用优化0比较稳妥吧。
下面是我查到的关于优化0,1,2,3的解释,英文版,你可以参考下
http://blog.csdn.net/yangtalent1206/article/details/8493120
还有一个思路就是楼上说的对某个子程序进行局部优化,下面是有关局部优化方法的链接
http://comm.chinaaet.com/adi/blogdetail/42068.html
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12208
金钱
12208
注册时间
2015-11-5
在线时间
2116 小时
发表于 2015-12-24 22:21:11 | 显示全部楼层
回复【11楼】等待烟花美:
---------------------------------
好的,非常感谢!
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-24 23:04:55 | 显示全部楼层
回复【12楼】FreeRTOS:
---------------------------------
哈,不客气,我也就知道这么多
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-25 21:54:58 | 显示全部楼层
FreeRTOS 发表于 2015-12-24 22:21
回复【11楼】等待烟花美:
---------------------------------
好的,非常感谢!

不好意思,还想请问下,你前面说的加上uint32_t  temp = 0x60010000;就不会进行读FLASH的原理是什么?
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12208
金钱
12208
注册时间
2015-11-5
在线时间
2116 小时
发表于 2015-12-25 23:22:53 | 显示全部楼层
等待烟花美 发表于 2015-12-25 21:54
不好意思,还想请问下,你前面说的加上uint32_t  temp = 0x60010000;就不会进行读FLASH的原理是什么?

不完全是不读FLASH,而是只读一次,就是让temp赋初始值,如果有通用寄存器可用的话,编译器会优先选用通用寄存器来替代temp,这样之后每次对temp的操作相当于对通用寄存器的操作,即使将temp改成 volatile uint32_t temp = 0x60010000; 这样temp不使用通用寄存器而是使用SRAM,操作时也比每次读FLASH强
拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

8

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-7-13
在线时间
4 小时
 楼主| 发表于 2015-12-26 14:58:37 | 显示全部楼层
FreeRTOS 发表于 2015-12-25 23:22
不完全是不读FLASH,而是只读一次,就是让temp赋初始值,如果有通用寄存器可用的话,编译器会优先选用通 ...

明白了,谢啦
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 21:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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