最近进行论文复现,涉及一些底层编程知识,做个笔记共同学习,不足之处还望及时指出
官方讲解
本文的内参考来自Microsoft官网,想要更多更全面的信息可以点击下方链接跳跃至官网学习
官网
基本语法
optimize(" ",on)
optimize(" ",off)
" "
中填参数,示例:
#pragma optimize("gt", on)
/Og
启用全局优化,优化局部和全局公共子表达式消除
、自动注册
、循环优化
,
现已弃用,因为上述优化措施已经默认开启。
optimize 杂注的参数
参数 | 优化的类型 |
---|---|
g | 启用全局优化。 已弃用。 有关详细信息,请参阅 /Og(全局优化)。 |
s 或 t | 指定机器代码的短或快速序列。 |
y | 在程序堆栈上生成帧指针。 |
提供局部和全局优化、自动寄存器分配和循环优化
- 局部和全局公共子表达式消除
在这个优化中,一个公共子表达式的值被计算一次。 在以下示例中,如果b
和 c
的值在三个表达式之间没有变化,编译器可以将 b + c
的计算分配给一个临时变量temp,并将该变量用于 b + c
:
a = b + c;
d = b + c;
e = b + c;
优化后仅记录一次b+c
的值
a = temp;
d = temp;
e = temp;
- 对于
局部公共子表达式优化
,编译器检查公共子表达式的一小段代码
。 - 对于
全局公共子表达式优化
,编译器在整个函数中
搜索公共子表达式。
- 自动注册分配
这种优化允许编译器将经常使用的变量和子表达式存储在寄存器中。 默认情况下忽略register
关键字,这会在 /std:c++17
或更高版本的情况下导致诊断。
- 循环优化
这种优化从循环体中删除了不变的子表达式。 最佳循环仅包含在每次执行循环时值发生变化的表达式。 在下面的例子中,循环体中的表达式 x + y
没有改变:
i = -100;
while( i < 0 ) {
i += x + y;
}
优化后,计算一次 x + y
,而不是每次执行循环都计算:
i = -100;
t = x + y;
while( i < 0 ) {
i += t;
}
当编译器可以假设没有别名时,循环优化会更有效,可以使用 __restrict、noalias 或 restrict 来设置别名。
/Os
& /Ot
/Os
和 /Ot
编译器选项指定在优化代码时是大小优先
(/Os
) 还是速度优先
(/Ot
)。
-
/Os(代码大小优先)
通过指示编译器优先优化大小而不是速度来最小化 EXE 和 DLL 的大小。 编译器可以将许多 C 和 C++ 构造简化为功能相似的计算机代码序列。 有时,这些差异会在大小与速度之间进行权衡。 可以使用 /Os 和 /Ot 选项为其中一个指定优先级: -
/Ot(代码速度优先)
通过指示编译器优先优化速度而不是大小来最大化 EXE 和 DLL 的速度。 启用优化时,/Ot 为默认值。 编译器可以将许多 C 和 C++ 构造简化为功能相似的计算机代码序列。 有时,这些差异会在大小与速度之间进行权衡。 /O2(最大化速度)选项隐含了 /Ot 选项。 /O2 选项组合了多个选项来生成更快的代码。
/O1
& /O2
/O1
和 /O2
编译器选项是一次性设置多个特定优化选项的快速方法。 /O1
选项设置可在大多数情况下创建最少代码的单个优化选项。 /O2
选项设置可在大多数情况下创建最快代码的选项。/O2
选项是发布版本的默认选项。 下表显示了由 /O1
和/O2
设置的特定选项:
选项 | 等效于 |
---|---|
/O1(最小化大小) | /Og /Os /Oy /Ob2 /GF /Gy |
/O2(最大化速度) | /Og /Oi /Ot /Oy /Ob2 /GF /Gy |
/O1 和 /O2 互斥。