C++;:仅在未设置时设置布尔值 我在C++应用程序中有代码,一般都是这样的: bool myFlag = false; while (/*some finite condition unrelated to myFlag*/) { if (...) { // statements, unrelated to myFlag } else { // set myFlag to true, perhaps only if it was false before? } } if (myFlag) { // Do something... }
我的问题与我的代码的C++;:仅在未设置时设置布尔值 我在C++应用程序中有代码,一般都是这样的: bool myFlag = false; while (/*some finite condition unrelated to myFlag*/) { if (...) { // statements, unrelated to myFlag } else { // set myFlag to true, perhaps only if it was false before? } } if (myFlag) { // Do something... },c++,boolean,variable-assignment,conditional-statements,compiler-optimization,C++,Boolean,Variable Assignment,Conditional Statements,Compiler Optimization,我的问题与我的代码的else语句有关。基本上,我的循环可以根据不满足的特定条件将myFlag的值从false设置为true。旗帜永远不会从真变假。我想知道哪条语句在性能方面更有意义,也许这个问题实际上不是编译器优化的问题 myFlag = true; 或 我通常会选择前者,因为它需要编写更少的代码。然而,我开始怀疑它是否涉及到对内存的不必要的写入,因此如果myFlag已经为真,那么后者将阻止不必要的写入。但是,使用后者会花费更多的时间吗?因为有一个条件语句,因此使用更多的指令编译代码 也许我想
else
语句有关。基本上,我的循环可以根据不满足的特定条件将myFlag的值从false设置为true。旗帜永远不会从真变假。我想知道哪条语句在性能方面更有意义,也许这个问题实际上不是编译器优化的问题
myFlag = true;
或
我通常会选择前者,因为它需要编写更少的代码。然而,我开始怀疑它是否涉及到对内存的不必要的写入,因此如果myFlag已经为真,那么后者将阻止不必要的写入。但是,使用后者会花费更多的时间吗?因为有一个条件语句,因此使用更多的指令编译代码
也许我想得太多了
更新1
只是想澄清一点……后一种情况的目的是,如果变量已经为真,就不要写入内存。因此,只有在变量为false时才写入内存。您是否意识到检查没有意义?如果您盲目地将其设置为
true
,但未设置,则您正在设置它。如果它已经是真的
,则没有更改,并且您正在不设置它,因此您可以有效地将其实现为:
myFlag = true;
关于潜在的优化,为了能够进行测试,值必须在缓存中,因此大部分成本已经支付。另一方面,分支(如果编译器没有优化
if
away,大多数人会这样做)会对性能产生更大的影响代码>考虑一下:即使编译器没有进行优化(不太可能),只需设置一条asm
语句,并且检查if
至少需要1条asm
语句
那就去做作业吧
更重要的是,不要试图对这些低级细节做出假设,特定的编译器优化完全可能违背直觉。您几乎可以肯定,使用
myFlag=true代码>
如果(!myFlag)myFlag=true,那么您可以从中得到最好的结果代码>是指编译器会注意到if
是不相关的,并对其进行优化。特别是,if
语句需要读取myFlag
的当前值。如果该值不在缓存中,这意味着指令将在等待从内存读取数据时暂停
相反,如果只写(不先测试),则可以将值写入写入写入队列,然后可以立即执行更多指令。除非您读取myFlag的值(并且假设它在写入后很快被读取,它很可能仍在缓存中,因此暂停将是最小的),否则您不会得到暂停。您很可能像其他人已经提到的那样考虑过这个问题,所以让我也这样做。如果您能够负担得起将与myFlag
无关的语句增加一倍,则以下操作可能会更快。事实上,您可以去掉myFlag
。好的,我们开始:
while (/*some finite condition*/) {
if (...) {
// statements
} else {
while (/*some finite condition*/) {
if (...) {
// statements, repeated
}
}
// Do something (as if myFlag was true in the OPs example)
break;
}
}
与所有性能优化一样:测量,测量,测量 如果(!myFlag)myFlag=true,是否代码>比简单的myFlag=true需要更多的时间来执行代码>即使没有任何优化。有些架构(例如)中,两条语句的执行都只需一个周期
在你的机器上计算的唯一方法是测量
在任何情况下,如果(!myFlag)myFlag=true,则myFlag=true将始终比更快或具有与相同的执行时间代码>这个问题也让我头疼,所以我只是用下面的代码(C#)自己测试了一下:
结果:
比较+设置-1个刻度
比较-1个刻度
设置-0个刻度
虽然用于设置值的时间肯定不是零,但它表明即使是单个查询也需要比设置变量更多的时间。您考虑得太多了。通常,myFlag=true
会更快,但是当您想知道什么更快时,您必须在自己的系统上对其进行分析。您只需将不必要的写入替换为不必要的读取和分支,猜猜哪一个更慢。你唯一需要担心的是当你在写与其他线程共享的变量时。如果MyFLAG被共享(它不在你的情况下),那么不加区分地写入它会使缓存行<代码>脏< /代码>,它会把它从所有可能有“<代码>干净\ < />代码>的其他内核中窥探,并且你必须考虑<代码>错误共享< /C>”——但是我正在思考答案:-如果布尔在内存中,内存的读/写很可能是瓶颈,而不是CPU。好吧,但无论如何,您必须从内存中获取它来计算if
,然后它很可能会留在缓存中。因此,在这两种情况下都需要访问内存,除非它已经在缓存中。CPU可能在写入时暂停,但在读取时不会暂停。杰凯德利:哦,是的,至少在理论上是这样(例如,如果你只有直写缓存)。导致写作速度变慢的原因不仅仅是“不太可能”,而是介于“极其罕见”和“纯粹理论”之间。
while (/*some finite condition*/) {
if (...) {
// statements
} else {
while (/*some finite condition*/) {
if (...) {
// statements, repeated
}
}
// Do something (as if myFlag was true in the OPs example)
break;
}
}
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
int i = 0;
int j = 1;
time.Start();
if (i != 0)
i = 0;
time.Stop();
Console.WriteLine("compare + set - {0} ticks", time.ElapsedTicks);
time.Reset();
time.Start();
if (j != 0)
j = 0;
time.Stop();
Console.WriteLine("compare - {0} ticks", time.ElapsedTicks);
time.Reset();
time.Start();
i = 0;
time.Stop();
Console.WriteLine("set - {0} ticks", time.ElapsedTicks);
Console.ReadLine();