MDK C++中对内联的极度优化
先来看看我们SmartIRQ的具体实现
// 智能IRQ,初始化时备份,销毁时还原
class SmartIRQ
{
public:
force_inline SmartIRQ(bool enable = false)
{
_state = __get_PRIMASK();
if(enable)
__enable_irq();
else
__disable_irq();
} force_inline ~SmartIRQ()
{
__set_PRIMASK(_state);
} private:
uint _state;
};
在构造的时候备份,然后根据参数决定打开还是关闭中断。
在系统内核时钟里面,关键操作需要关闭中断,最后打开,以免其它中断影响关键操作的原子事务性。
于是我们有:
ulong Time::CurrentTicks()
{
SmartIRQ irq; uint value = (SysTick->LOAD - SysTick->VAL);
if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG)
{
Ticks += SysTick->LOAD;
} return Ticks + value;
}
其中irq在离开作用域时被释放,自动调用SmartIRQ的析构函数,还原了中断状态
因为调用极其频繁,最高可能1us调用一次该函数,于是我们给SmartIRQ的构造和析构都加了force_inline强制使用内联。
总所周知,C++的内联其实就是以空间换时间,把一个函数的代码全部搬出来直接使用,省去了调用、压栈、弹栈、返回等操作。
SmartIRQ的析构函数就罢了,但是构造函数代码量还是有好几行的。
怀着试一试的心态调试该函数,直接观察汇编代码:
0x08000804 B570 PUSH {r4-r6,lr}
0x08000806 F3EF8210 MRS r2,PRIMASK
0x0800080A B672 CPSID I
0x0800080C 4D0B LDR r5,[pc,#] ; @0x0800083C
0x0800080E LDR r1,[r5,#0x14]
0x08000810 69AB LDR r3,[r5,#0x18]
0x08000812 1ACC SUBS r4,r1,r3
0x08000814 LDR r1,[r5,#0x10]
0x08000816 MOVS r3,#0x00
0x08000818 03C9 LSLS r1,r1,#
0x0800081A CMP r1,#0x00
0x0800081C DA06 BGE 0x0800082C
0x0800081E LDR r6,[r0,#0x08]
0x08000820 68C1 LDR r1,[r0,#0x0C]
0x08000822 696D LDR r5,[r5,#0x14]
0x08000824 ADDS r5,r6,r5
0x08000826 ADCS r1,r1,r3
0x08000828 STR r5,[r0,#0x08]
0x0800082A 60C1 STR r1,[r0,#0x0C]
0x0800082C LDR r5,[r0,#0x08]
0x0800082E 68C1 LDR r1,[r0,#0x0C]
0x08000830 ADDS r0,r5,r4
0x08000832 ADCS r1,r1,r3
0x08000834 F3828810 MSR PRIMASK,r2
0x08000838 BD70 POP {r4-r6,pc}
MDK C++编译器优化到了极度变态的地步!
不仅仅内联了,SmartIRQ里面有两个分支语句,直接被他省略了其中一个,因为参数true已经确定。
更加变态的是,本来采用SmartIRQ内部私有成员_state保存状态,析构时恢复的,它直接把这个状态保存到寄存器r2里面去,连_state的内存都给省了。
MDK C++中对内联的极度优化的更多相关文章
- 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表
一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...
- C++中内联函数
目录 什么是内联函数 如何使函数内联 为什么要使用内联函数 inline函数的优缺点分析 什么时候该使用内联函数 正文 在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么 ...
- MDK/Keil 中,J-Link调试查看变量值总是显示<not in scope>
转载请注明出处,谢谢. MDK/Keil 中,J-Link调试查看变量值总是显示<not in scope> 原因:编译器把代码优化掉了,直接导致在仿真中变量根本没有分配内存,也就无法查看 ...
- Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)【转】
转自:http://www.linuxidc.com/Linux/2013-06/85221p3.htm 阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入 ...
- 关于margin、padding 对内联元素的影响
内联元素和块级元素的区别是新手必须要掌握的知识点.大家可能平时注意块级元素比较多.所以这里重点让我们来讲讲常见的width height margin padding 对inline元素的影响. 测 ...
- MySQL中的SQL的常见优化策略
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 1 避免全表扫描对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索 ...
- 关于js-binding中Layer触摸事件的优化
关于js-binding中Layer触摸事件的优化 cocos2d-x 3.7 1. 目前js中监听触摸事件带来的不便(特别是cocosbuilder) 在目前的js-binding中,如果要监听la ...
- OpenCV中的SVM參数优化
SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最经常使用的是用于分类,只是SVM也能够用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,opencv ...
- Android 关于ListView中按钮监听的优化问题(方法二)
关于ListView中按钮监听的优化问题(方法一)地址: http://www.cnblogs.com/steffen/p/3951901.html 之前的方法一,虽然能够解决position的传递, ...
随机推荐
- SpringCloud四:hystrix-propagation
注:pom.xml 及配置文件配置与上篇相同 package com.itmuch.cloud.controller; import org.springframework.beans.factory ...
- 微信小程序——微信支付
这个讲起来也就比较麻烦一点,因为需要的不仅仅是咱们代码上的技术,嘿嘿! 先整理一下思路.如果想做微信支付: 1.现有一个公司账户(非个人账户),并且实名认证过的. 2.微信号 必须开通微信支付功能. ...
- 成功解决react+webpack打包文件过大的问题
最近在学习并使用webpack+react+antd写了一个小项目,也可以说是demo,待全部开发完成后发现webpack的打包文件足足有将近13.3MB,快吓死宝宝了,经过连续几天的学习,和调试最后 ...
- 【python】字符串变量赋值时字符串可用单或双引号
>>> name='萧峰' >>> print(name) 萧峰 >>> name="独孤求败" >>> p ...
- 代码生成利器:IDEA 强大的 Live Templates(转)
代码生成利器:IDEA 强大的 Live Templates - 文章 - 伯乐在线http://blog.jobbole.com/110607/ 前言 Java 开发过程经常需要编写有固定格式的代码 ...
- Python Web框架
本节对Python Web框架学习 一.MTVModel: 存放所有数据库相关文件Template:模板文件,存放html文件View: 业务处理,即函数文件 二.MVCmodel: 存放数据库相关文 ...
- Java零碎总结
获取当前类运行的根目录(即classpath,如bin.classes.AppName等)的方式有: 1.Thread.currentThread().getContextClassLoader(). ...
- Java中 &&与&,||与|的区别
区别 && || 是逻辑运算,支持短路运算 & | 是位运算,不支持短路运算 短路运算 当有多个表达式时,左边的表达式值可以确定结果时,就再继续运算右边的表达式的值; 举例 ...
- 《Linux系统编程手册》读书笔记——第2章基本概念
操作系统的核心--内核 内核的职责 进程调度:Linux属于抢占式多任务操作系统,多个进程可同时驻留于内存,且每个进程都能获得对CPU的使用权.哪些进程获得对CPU的使用,以及每个进程能使用多长时间 ...
- jquery UI autocomplete当输入框焦点聚焦时自动弹出跟随下拉框
$("#search").autocomplete({ minLength: 0, source: function(request,response){ // request对象 ...