Rus*_*lan 116 c++ optimization
考虑以下功能:
void func(bool& flag)
{
if(!flag) flag=true;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,如果flag有一个有效的布尔值,这相当于无条件设置它true,如下所示:
void func(bool& flag)
{
flag=true;
}
Run Code Online (Sandbox Code Playgroud)
然而,gcc和clang都没有这样优化它 - 都在-O3优化级别生成以下内容:
_Z4funcRb:
.LFB0:
.cfi_startproc
cmp BYTE PTR [rdi], 0
jne .L1
mov BYTE PTR [rdi], 1
.L1:
rep ret
Run Code Online (Sandbox Code Playgroud)
我的问题是:只是代码太特殊flag而不关心优化,或者是否有任何好的理由为什么这样的优化是不希望的,因为它不是一个参考volatile?看来这可能是唯一的原因是,flag可以在某种程度上具有非true-或- false在阅读它的点不未定义行为的价值,但我不知道这是否是可能的.
Leo*_*eon 102
由于高速缓存一致性考虑,这可能对程序的性能产生负面影响.写入flag每次func()被称为会弄脏包含高速缓存行.无论写入的值与写入之前在目标地址处找到的位完全匹配,都会发生这种情况.
编辑
hvd提供了阻止这种优化的另一个好理由.对于提议的优化,这是一个更有说服力的论据,因为它可能导致未定义的行为,而我的(原始)答案仅解决了性能方面.
经过多一点反思之后,我可以提出另一个例子,为什么编译器应该被强烈禁止 - 除非他们能够证明转换对于特定的上下文是安全的 - 从引入无条件写入.考虑以下代码:
const bool foo = true;
int main()
{
func(const_cast<bool&>(foo));
}
Run Code Online (Sandbox Code Playgroud)
使用无条件写入func()肯定会触发未定义的行为(写入只读存储器将终止程序,即使写入的效果否则将是无操作).
小智 48
除了莱昂对绩效的回答:
假设flag是true.假设两个线程一直在调用func(flag).在这种情况下,写入的函数不会存储任何内容flag,因此这应该是线程安全的.两个线程可以访问同一个内存,但只能读取它.无条件设置flag至true意味着两个不同的线程将被写入同一个存储.这是不安全的,即使写入的数据与已经存在的数据相同,这也是不安全的.
glg*_*lgl 13
我不确定这里的C++的行为,但是在C中,内存可能会改变,因为如果内存包含非零的非零值,它将在检查时保持不变,但在检查时更改为1.
但由于我不熟悉C++,我不知道这种情况是否可行.
| 归档时间: |
|
| 查看次数: |
6923 次 |
| 最近记录: |