C++优化相关的关键字学习
inline
即汇编内联展开,仅作用于函数定义
gcc 8.1.0
-
c标准
- ANSI C, C99, C11
- 其实 C89 与 C90 都是 ANSI C,因为这是两个组织对同一个标准的不同命名
-
c++标准
- C++98, C++11, C++14, C++17
-
c89标准中
不支持inline
关键字 -
c99标准、c11标准中
- inline: 不开优化,不会内联,不会生成独立代码(仅作用于定义时);开优化,仅内联,不会生成独立代码,需要用到函数地址的地方将使用外部同名函数,外部可访问。
- extern inline: 不开优化,不会内联,会生成独立代码;开优化,优先内联(当前源码),总是生成独立代码,外部可访问。
- static inline: = 不开优化,不会内联,会生成独立代码;开优化,优先内联(当前源码),必要时(需要用到函数地址的地方)生成独立代码,外部不可访问。
-
g++
inline: 开优化则内联,否则独立代码
restrict
restrict用于修饰一个指针,告诉编译器,在作用域内,它指向的对象仅又该指针引用(不存在其他线程引用),从而让编译器可优化代码
例如:
int foo(int* a, int* b)
{
*a = 1;
*b = 2;
return *a + *b;
}
int foo(int* restrict a, int* restrict b);
在没有声明restrict前,编译器不知道 a 和 b 会不会指向相同的地址,因此,每次*a
都会进行解引用操作,即从内存相应地址处取值(或写入),需要访问内存(当缺页时,甚至需要访问磁盘)。
但是当声明为restrict了后,在*a
的作用域内,对*a
的读写都会映射到cpu寄存器,访问速率要远远大于访问内存,只在满足下列条件之一,才会访问内存:
- 最后一次写。
- 第一次读,且之前没有执行过写指令。
auto、volatile、register
- auto 即自动变量,一般用于栈变量,用于全局变量应该是没有作用的,一般在函数中声明的变量没有特别声明时,都是自动变量,何谓“自动”,就是由编译器自动判断变量放到栈中还是寄存器中,即由编译器决定是volatile还是register
- register 即寄存器变量,告诉编译器,将改变了放到寄存器当中,这类变量会在gdb调试时被提示为“optimized out”,即“优化掉了”
- volatile 即易变变量,告诉编译器,这个变量在内存中的值可能由其他地方(通过地址)修改,此时编译器就会将该变量放到栈中,每次访问都会去栈中取值
注:一般unix派操作系统对longjmp的实现不会回滚寄存器和自动为寄存器的变量,想想,还想也不好回滚。