Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 奇怪的优化?在'libuv'中。请解释一下_C++_C_Optimization_Compiler Optimization_Libuv - Fatal编程技术网

C++ 奇怪的优化?在'libuv'中。请解释一下

C++ 奇怪的优化?在'libuv'中。请解释一下,c++,c,optimization,compiler-optimization,libuv,C++,C,Optimization,Compiler Optimization,Libuv,libuv包含core.c:uv\u run() 这是什么意思?这是某种优化吗?为什么他们不简单地分配0?是的,正如评论所说。如果标志已经为0,则无需将任何数据写入内存,从而避免缓存中现有数据可能被逐出,并将其替换为标志的0。这将只在时间非常关键的应用程序中提供附加值。我认为这种优化是不好的。例如,在带有-O3的gcc上,它给出了以下代码: foo(): movl stop_flag(%rip), %eax testl %eax, %eax

libuv
包含
core.c:uv\u run()


这是什么意思?这是某种优化吗?为什么他们不简单地分配0?

是的,正如评论所说。如果标志已经为0,则无需将任何数据写入内存,从而避免缓存中现有数据可能被逐出,并将其替换为标志的0。这将只在时间非常关键的应用程序中提供附加值。

我认为这种优化是不好的。例如,在带有-O3的gcc上,它给出了以下代码:

foo():
        movl    stop_flag(%rip), %eax
        testl   %eax, %eax
        je      .L3
        movl    $0, stop_flag(%rip)
.L3:
        ret
stop_flag:
        .zero   4

如您所见,没有条件移动,只有一个分支。我敢肯定,分支预测失误远比弄脏缓存线更糟糕。

评论解释了这一点。可能是你的错,但不是我的错。何时以及如何工作?对于现代C++编译器来说,这仍然是实际的吗?编译器没有缓存行,处理器也没有。如果内存已经设置为0,它们不想修改内存。@ ToMasMatthWS,我想它可以被问到:“编译器自己不会处理它吗?”或者相反,它不会把它优化成一个简单的任务吗?这是为了避免“错误共享”吗??我不认为这是逐出问题,这是回写问题(当它是脏线时)。处理器可能需要读取变量,因此变量可能在缓存中,或者处理器可能必须将变量放入缓存中才能读取。我不知道写入相同的值是否真的会弄脏它。可能取决于硬件。现在分支与无条件写入的成本是多少?看看什么更快会很有趣。分支非常繁重,比赋值更糟糕。这是CPU管理员的常识。但作为@EugeneSh。戏剧性地指出,你必须提供一个链接让OP看到。@EugeneSh.,我没有确凿的证据,但它似乎是合乎逻辑的。毕竟,没有什么能阻止CPU在看到值没有实际更改的情况下不使缓存失效——但预测失误总是有可能的。写入内存位置可能比分支预测失误慢得多。如果核心仅具有缓存线的共享所有权,则它必须向所有其他核心广播失效请求以使其副本失效。如果任何其他内核都处于修改状态,它必须发回缓存线并将其与当前内核合并。由于这涉及到跨核心互连的多个回退和Forth,因此我们所说的延迟大于缓存未命中(数百个周期),而不是分支预测失误的10个ish。@SergeyA如果分支在大多数情况下被执行(未执行),那么分支预测器在大多数情况下都是准确的,因此,对于大量迭代,优化可能会获得收益。当然,这取决于整个画面。@神秘的是,如果该值已被读取,除非该行在缓存中,否则无论如何都可以访问内存。另外,处理器可能会首先在一致性协议中请求线路作为
共享
,因此通过这种方式,您可能会获得两倍的一致性开销。再加上写操作可以在不影响处理器的情况下进行缓冲,我真的对这种“优化”持怀疑态度。
foo():
        movl    stop_flag(%rip), %eax
        testl   %eax, %eax
        je      .L3
        movl    $0, stop_flag(%rip)
.L3:
        ret
stop_flag:
        .zero   4