先来看看我们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. MQTT 设计原则

    MQTT 设计原则 简单. 没有杂七杂八的花俏功能,作为一个基础组件构建实用的系统,易于实现. "发布/订阅"消息传递方式. 随时接入随时发布.接收消息,无需太多其他"事 ...

  2. 如何把git仓库(包含所有提交历史)迁移到gitlab

    在gitlab上new 一个project 跳转到本地的git 目录中,运行命令 git remote add gitlab gitlab_new_project_address -最后运行如下命令, ...

  3. MVC+EF 入门教程(三)

    一.前言 上一节,我们将了生成数据库,那么这张我就将操作设计库. 二.在 Aplication 定义服务 在 Application 中添加文件夹(Blog)和 操作类(BlogServer).实例如 ...

  4. 解决win7中防火墙的0x6D9问题的方法

    问题: 打开windows防火墙管理单元时出错:代码0x6d9" 解决方法: 下一步-->下一步-->完成.

  5. ios单独的页面支持横竖屏的状态调整,HTML5加载下(更新2)

    单独的页面支持横竖屏的状态调整,HTML5加载下 工程中设置只支持竖屏状态,在加载HTML5的界面可以是横竖屏的,在不对工程其他界面/设置做调整的同时,可以这样去 #import "View ...

  6. Spring+MVC+Mybatis整合

    本文是对慕课网上"搞定SSM开发"路径的系列课程的总结,详细的项目文档和课程总结放在github上了.点击查看 什么是秒杀业务 网站售卖某产品时,规定在某个日期开始售卖限量的产品, ...

  7. 回顾2017系列篇(二):移动端APP设计趋势

    移动端APP在2017年经历了诸多的变化, 人工智能.聊天式的界面.响应式设计.虚拟现实(VR)和增强现实(AR)让设计师不断面临新的挑战.研究表明,用户每天耗费在手机和平板上的平均时长为158分钟, ...

  8. vue基础入门

    Hello World   <body> <!-- 在angularJS中用ng-model --> <!-- {{mseeage?message:11}}支持三元表达式 ...

  9. java inputstream to string stack overflow

    https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string 过千赞的答案

  10. 对DataTable(或者DataSet)修改后,提交修改到数据库

    http://blog.csdn.net/nidexuanzhe/article/details/8228832 说明:通常我们在做数据库交互时,并不一定要使用特定的SQL语句来更新数据,.NET F ...