构造长循环语句是一种好的做法吗
Is it good practice to construct long circuit statements?
问题上下文:[C++]我想知道理论上什么是最快的,编译器会做什么。我不想听到过早优化是万恶之源等。
我在写这样的代码:
bool b0 = ...;
bool b1 = ...;
if (b0 && b1)
{
...
}
但后来我在想:如果在没有优化的情况下编译,代码将按原样编译成两个TEST指令。这意味着两个分支。所以我在想,最好写:
if (b0 & b1)
如果编译器没有进行优化,它将只生成一条TEST指令。但后来我觉得这违背了我的代码风格。我通常写&&
和||
。
Q:如果我打开优化标志(-O1
、-O2
、-O3
、-Os
和-Ofast
),编译器会怎么做。即使我在代码中使用了&&
,编译器会像&
一样自动编译它吗?理论上什么更快?如果我这样做,行为会改变吗:
if (b0 && b1)
{ ... }
else if (b0)
{ ... }
else if (b1)
{ ... }
else
{ ... }
Q:正如我所猜测的,这在很大程度上取决于情况,但编译器用&
替换&&
是一种常见的技巧吗?
Q: 如果我打开优化标志(-O1、-O2、-O3、-Os和-Ofast),编译器会怎么做。
很可能没有更多的东西来增加优化。正如我在评论中所说,你真的不能再优化评估了:
AND B0 WITH B1 (sets condition flags)
JUMP ZERO TO ...
尽管如此,如果您有很多简单的布尔逻辑或数据操作,一些处理器可能会有条件地执行它们。
编译器会自动编译它吗;,即使我使用了&;代码中
理论上什么更快?
在大多数平台中,A & B
与A && B
的评估没有差异
在最终评估中,执行比较或AND指令,然后根据状态进行跳转。两条说明。
大多数处理器没有布尔寄存器。都是数字和比特。
通过布尔逻辑优化
你最好的选择是审查设计,并设置你的算法使用布尔代数。您可以简化布尔表达式。
另一种选择是实现代码,以便编译器可以生成条件汇编指令(如果平台支持的话)。
优化:减少跳跃
处理器更喜欢算术和数据传输,而不是跳跃。
许多处理器总是向指令管道提供信息。当涉及到条件分支指令时,处理器必须等待(暂停指令预取),直到确定条件状态。然后它可以确定下一条指令将被提取到哪里。
如果不能消除跳跃,例如在循环中,则在数据端增大数据处理与跳跃的比率。搜索"循环展开"。当优化级别增加时,许多编译器将执行此操作。
优化:数据缓存
通过组织数据以获得最佳数据缓存使用率,您可能会注意到性能的提高。
例如,使用包含3个元素的结构的一个阵列,而不是3个大阵列。这允许使用中的元素彼此靠近(并降低访问缓存外数据的可能性)。
摘要
A && B
与A & B
作为条件表达式的评估差异被称为微优化。通过使用布尔代数来减少条件表达式的数量,可以提高性能。跳转或更改执行路径会减慢指令执行速度。从数据缓存之外获取数据也会减慢执行速度。通过重新设计代码并帮助编译器减少分支和更有效地使用数据缓存,您很可能会获得更好的性能。
如果你关心什么是最快的,为什么你关心编译器在没有优化的情况下会做什么?
Q:正如我所猜测的,这在很大程度上取决于情况,但编译器用
&
替换&&
是一种常见的技巧吗?
这个问题似乎假设编译器将C++代码转换为更多的C++代码。事实并非如此。它将代码转换为机器指令(为了参数起见,将汇编程序作为编译器的一部分)。您不应该假设存在从像&&
或&
这样的C++运算符到特定指令的一对一映射。
通过优化,编译器将执行它认为更快的任何操作。如果一条指令会更快,编译器会为if (b0 && b1)
生成一条指令,那么你不需要用微优化来帮助代码进行如此简单的转换。
编译器知道它正在使用的指令集,它知道条件所在的上下文,以及它是否可以作为死代码完全删除,或者移动到其他地方以帮助管道,或者通过不断传播来简化,等等。
如果你真的关心什么是最快的,为什么要计算b1
,直到你知道它是真正需要的?如果获得b1
的值没有副作用,编译器甚至可以将代码转换为:
bool b0 = ...;
if (b0)
{
bool b1 = ...;
if (b1)
{
这是否意味着两个if
条件比一个&
条件快?!当然不是。
换句话说,这个问题的整个前提是有缺陷的。不要在错误地追求"理论上最快"的微优化的过程中损害代码的可读性和简单性。花时间改进所使用的算法和数据结构,而不是尝试猜测编译器将生成哪些指令。
- 有没有一种方法可以使用弗洛伊德-沃歇尔算法给出最短路径,其中存在负权重循环而不允许重叠边缘?
- 是否有一种方法可以在运行时停止循环重复一次不止一次
- 我想不出一种方法来使我的代码循环
- 有没有一种方法可以关闭C++和Rust编译中的循环优化
- 有没有一种方法可以访问for循环块之外的变量
- 在"for"循环条件下使用 "ternary operation" 是一种好的做法吗?
- C++-使用循环的另一种方法
- 构造长循环语句是一种好的做法吗
- 有没有一种方法可以在变量之间循环?(C++)
- 嵌套渲染循环是不是一种糟糕的做法
- 思考一种不同的方式来运行win32事件循环没有WndProc
- 从套接字接收消息的无限循环内ussleep的另一种方式
- 一种分配和初始化数组的方法,比普通的循环和设置更快
- 这在多大程度上是一种不好的做法?(循环依赖)
- 我需要以一种可以从循环调用构造函数的方式组织我的类
- 一种更有效的处理循环内列表参数的方法
- 一种涉及比较函子的循环依赖关系
- 有没有一种方法可以在没有while循环的情况下在计算机之间传输数据?c++
- 有没有一种方法可以在for循环中将多个变量推回到一个向量中
- 有没有一种方法可以简化这个c++整数循环数组?