先来看看我们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++中对内联的极度优化的更多相关文章

  1. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  2. C++中内联函数

    目录 什么是内联函数 如何使函数内联 为什么要使用内联函数 inline函数的优缺点分析 什么时候该使用内联函数 正文 在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么 ...

  3. MDK/Keil 中,J-Link调试查看变量值总是显示<not in scope>

    转载请注明出处,谢谢. MDK/Keil 中,J-Link调试查看变量值总是显示<not in scope> 原因:编译器把代码优化掉了,直接导致在仿真中变量根本没有分配内存,也就无法查看 ...

  4. Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)【转】

    转自:http://www.linuxidc.com/Linux/2013-06/85221p3.htm 阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入 ...

  5. 关于margin、padding 对内联元素的影响

    内联元素和块级元素的区别是新手必须要掌握的知识点.大家可能平时注意块级元素比较多.所以这里重点让我们来讲讲常见的width height margin  padding 对inline元素的影响. 测 ...

  6. MySQL中的SQL的常见优化策略

    MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 1 避免全表扫描对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索 ...

  7. 关于js-binding中Layer触摸事件的优化

    关于js-binding中Layer触摸事件的优化 cocos2d-x 3.7 1. 目前js中监听触摸事件带来的不便(特别是cocosbuilder) 在目前的js-binding中,如果要监听la ...

  8. OpenCV中的SVM參数优化

    SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最经常使用的是用于分类,只是SVM也能够用于回归,我的实验中就是用SVM来实现SVR(支持向量回归). 对于功能这么强的算法,opencv ...

  9. Android 关于ListView中按钮监听的优化问题(方法二)

    关于ListView中按钮监听的优化问题(方法一)地址: http://www.cnblogs.com/steffen/p/3951901.html 之前的方法一,虽然能够解决position的传递, ...

随机推荐

  1. 5. Effective Java 第三版——使用依赖注入取代硬连接资源

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. linux(ubuntu) 搭建java程序运行环境

    一:简介 ubuntu 系统的和linux差不多,我们需要在系统上搭建java程序运行环境,需要安装jdk,mysql这两个软件,tomcat是绿色版,直接通过taz -zxvf tomcat 就可以 ...

  3. 微信小程序——微信支付

    这个讲起来也就比较麻烦一点,因为需要的不仅仅是咱们代码上的技术,嘿嘿! 先整理一下思路.如果想做微信支付: 1.现有一个公司账户(非个人账户),并且实名认证过的. 2.微信号 必须开通微信支付功能. ...

  4. 商城项目回顾整理(二)easyUi数据表格使用

    后台主页: 商品的数据表格展示 引入用户表数据表格展示 引入日志表数据表格展示 引入订单表数据表格展示 后台主页代码: <%@ page language="java" co ...

  5. Akka Cluster简介与基本环境搭建

      akka集群是高容错.去中心化.不存在单点故障以及不存在单点瓶颈的集群.它使用gossip协议通信以及具备故障自动检测功能. Gossip收敛   集群中每一个节点被其他节点监督(默认的最大数量为 ...

  6. css弹性盒子新旧兼容

    前言:本篇随笔是对弹性盒子有了解的人来写的这篇文章,具体属性产生的效果这里不做说明,基础的东西去查文档.这里只是总结. 时至今日,css3的flex弹性盒子在移动端基本上都是支持的,但不排除有些些低版 ...

  7. Linux(CentOS6.5)下修改Nginx初始化配置

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢! 首先备份相关文件: cp /comexHome/nginx/conf ...

  8. Tomcat 组件介绍

    用了好长时间tomcat,但是其实自己只是反复听了这个名字,对Tomcat并不了解 1.Tomcat组件 Catalina Coyote Jasper Cluster 2.组件介绍 Tomcat Co ...

  9. 使用C#开发数据库应用系统 习题

    错题积累 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:

  10. Django__WSGI

    WEB应用的本质 : 1. 浏览器发送一个http请求 2. 服务器收到请求,生成一个html文档 3. 服务器把HTML文档作为HTTP响应的body发送给浏览器 4. 浏览器收到http响应,从h ...