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,#44]  ; @0x0800083C
0x0800080E 6969      LDR      r1,[r5,#0x14]
0x08000810 69AB      LDR      r3,[r5,#0x18]
0x08000812 1ACC      SUBS     r4,r1,r3
0x08000814 6929      LDR      r1,[r5,#0x10]
0x08000816 2300      MOVS     r3,#0x00
0x08000818 03C9      LSLS     r1,r1,#15
0x0800081A 2900      CMP      r1,#0x00
0x0800081C DA06      BGE      0x0800082C
0x0800081E 6886      LDR      r6,[r0,#0x08]
0x08000820 68C1      LDR      r1,[r0,#0x0C]
0x08000822 696D      LDR      r5,[r5,#0x14]
0x08000824 1975      ADDS     r5,r6,r5
0x08000826 4159      ADCS     r1,r1,r3
0x08000828 6085      STR      r5,[r0,#0x08]
0x0800082A 60C1      STR      r1,[r0,#0x0C]
0x0800082C 6885      LDR      r5,[r0,#0x08]
0x0800082E 68C1      LDR      r1,[r0,#0x0C]
0x08000830 1928      ADDS     r0,r5,r4
0x08000832 4159      ADCS     r1,r1,r3
0x08000834 F3828810  MSR      PRIMASK,r2
0x08000838 BD70      POP      {r4-r6,pc}

MDK C++编译器优化到了极度变态的地步!
不仅仅内联了,SmartIRQ里面有两个分支语句,直接被他省略了其中一个,因为参数true已经确定。
更加变态的是,本来采用SmartIRQ内部私有成员_state保存状态,析构时恢复的,它直接把这个状态保存到寄存器r2里面去,连_state的内存都给省了。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中类怎么理解_Python中的列表理解

python中类怎么理解In order to create a list, a most obvious and remembered solution is to use a for-loop. 为了创建列表,最明显和记住的解决方案是使用for循环。 Example: 例: Python 3.6.8 (default, Apr 25 2019, 21:02:35)[GCC 4.8.5 201506…

工控领域的网络攻击 食尸鬼行动深入解读Operation Ghoul

卡巴斯基于2016年6月监测到了Operation Ghoul(食尸鬼行动)网络攻击,Operation Ghoul针对30多个国家的工业、制造业和工程管理机构发起了定向渗透入侵。目前,卡巴斯基发现,有130多个机构已被确认为这类攻击的受害者。 该…

julia自然常数_Julia中的Sys.KERNEL常数

julia自然常数Julia| 系统内核常数 (Julia | Sys.KERNEL Constant) Sys.KERNEL is a constant of the Symbol type in Julia programming language, it is used to get the name of the operating system. Sys.KERNEL是Julia编程语言中Symbol类型的常量,用于获取操作…

tomcat:sessionId生成机制导致tomcat启动过慢问题

为什么80%的码农都做不了架构师?>>> http://blog.csdn.net/u013939884/article/details/72860358 转载于:https://my.oschina.net/wii01/blog/1527731

Codeforces Round #431 (Div. 2)

A. Odds and Endstime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputWhere do odds begin, and where do they end? Where does hope emerge, and will they ever break? Given an integer sequence a1, a2, ..., a…

ping/pong模式_PING的完整形式是什么?

ping/pong模式PING:数据包InterNet Groper (PING: Packet InterNet Groper) In the sector of networking of computers, PING is an abbreviation of Packet InterNet Groper. It is utility software or system software of administration of computer network u…

Gartner: 2017年11大信息安全技术(解读版)

在2017年6月份举办的第23届Gartner安全与风险管理峰会上,Gartner的Fellow——Neil McDonald发布了2017年度的11个最新最酷的信息安全技术,比往年的10大技术多了一项。以往都是通过互联网了解Gartner的各种信息和报告。这次,本人有幸亲临现场&…

博客url什么形式_URL的完整形式是什么?

博客url什么形式URL:统一资源定位符 (URL: Uniform Resource Locator) URL is an abbreviation of Uniform Resource Locator. Uniform Resource Locator which is informally or casually known as a web address is addressed as a resource of the web, which ca…

Verizon的SDN策略:不鸣则已,一鸣惊人?

Verizon对于其网络虚拟化计划的进展等一直保持缄默,但这并不代表Verizon没在SDN方面投入。 Verizon于2015年推出了初步的SDN迁移计划,但并未就此事对外界做过多披露。与此同时,它影响着它的SDN虚拟化合作伙伴。如电缆方面,据介绍&…

宝马奥迪工厂模式_宝马的完整形式是什么?

宝马奥迪工厂模式宝马:巴伐利亚汽车公司 (BMW: Bayerische Motoren Werke) BMW is an abbreviation of "Bayerische Motoren Werke". It is a multinational automobile and motorcycle manufacturing company whose headquarter is situated in Munich, …

艾拉物联CEO :物联网时代的到来让安全问题显得尤为突出

产品安全和嵌入式安全的理念一直都很复杂,不过我们至少对它们比较熟悉。但物联网(IoT)却对“产品”这一理念进行了颠覆,让联网成为了产品定义中不可或缺的一部分。 由此一来,仅在设备层面讨论安全已经远远不够了。不论…

jquery选择器连续选择_JQuery中的选择器

jquery选择器连续选择Its time to write some JQuery now. Do check out the introductory article on JQuery first in case you havent. Before we move to Selectors in JQuery, lets talk a bit about the general syntax first. 现在该写一些JQuery了。 如果没有&#xff…

加拿大大数据:正在升温的大数据市场

产业发展背景 早在2011年5月加拿大广播电视和电信委员会(CRTC)就发布了新的“国家宽带计划”,该计划显示,到2015年加拿大全体国民将享有5Mbps的宽带接入速度。CRTC表示:“来自市场的资金及有针对性的政府拨款将继续推动…

scala 多线程_Scala中的多线程

scala 多线程Scala多线程 (Scala Multithreading) Multithreading is the concept of using multiple threads simultaneously that allows the program to perform multiple operations simultaneously. 多线程是同时使用多个线程的概念,它允许程序同时执行多个操作…

split注意事项

为什么80%的码农都做不了架构师?>>> 1.特殊字符 “|”,“*”,“^”,".",“:”,使用此字符作为分割符,必须用\\加以转义 2.同时存在多个特殊字符的时候&#x…

Harbor升级和数据库迁移手册

Harbor升级和数据库迁移手册当升级一个已经存在的Harbor实例到新版本时,需要迁移数据库数据。参考Whats New in Harbor Database Schema查看数据库发生了哪些变化,如果有的话,就需要进行数据库迁移操作,因为迁移可能会改变数据库模…

Floyd Warshall算法

Description: 描述: This is a very popular interview problem to find all pair shortest paths in any graph. This problem has been featured in interview rounds of Samsung. 这是一个非常流行的面试问题,用于在任何图中找到所有对最短路径。 该…

Java多线程系列--“基础篇”09之 interrupt()和线程终止方式

2019独角兽企业重金招聘Python工程师标准>>> Java多线程系列--“基础篇”09之 interrupt()和线程终止方式 概要 本章,会对线程的interrupt()中断和终止方式进行介绍。涉及到的内容包括:1. interrupt()说明2. 终止线程的方式 2.1 终止处于“阻…

mac活动监视器_什么是活动监视器?

mac活动监视器活动监控 (Activity Monitor) Apple OS X provides the services of which one of them is Activity Monitor. Activity Monitor is used to monitor the activities of computer like active processes, processor load, applications that are running, and the…

concurrent包下的Exchanger练习

Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。 当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据…