问题标签 [likely-unlikely]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 在 if-else if 链中使用 Likely()/Unlikely() 预处理器宏
如果我有:
如果编译器不影响先前检查的分支预测,我可以在最后一个条件检查周围放置可能()else if (likely(Z))
来表示最终语句(else)不太可能吗?
基本上,如果有一个带有分支预测器提示的条件语句,GCC 是否会尝试优化整个 if-else if 块?
c++ - 如果不太可能出现硬崩溃错误,我应该使用吗?
我经常发现自己编写的代码看起来像这样:
我应该更喜欢用 处理错误if unlikely
吗?
编译器会自动推断代码的哪一部分应该被缓存,或者这是一个真正有用的事情吗?为什么我看不到很多人处理这样的错误?
c++ - 如何在 if-else 语句中使用 C++20 的可能/不太可能属性
这个问题是关于 C++20 的[[likely]]
/[[unlikely]]
特性,而不是编译器定义的宏。
本文档 ( cppreference ) 仅给出了将它们应用于 switch-case 语句的示例。这个 switch-case 示例与我的编译器 (g++-7.2) 完美编译,所以我假设编译器已经实现了这个特性,尽管它还没有在当前的 C++ 标准中正式引入。
但是当我像这样使用它们时:if (condition) [[likely]] { ... } else { ... }
,我收到了一个警告:
“警告:语句开头的属性被忽略 [-Wattributes]”。
那么我应该如何在 if-else 语句中使用这些属性呢?
c - 为什么可能和不太可能的宏对 ARM 汇编代码没有任何影响?
我从https://kernelnewbies.org/FAQ/LikelyUnlikely举了下面的例子
并用.https://godbolt.org/z/IC0aifarm gcc 8.2 compiler
编译它
在原始链接中,他们已经针对 X86 对其进行了测试,如果likely
(在上面代码中的 if 条件中)替换为,则汇编输出不同unlikely
,这表明编译器对分支预测进行了优化。
但是当我为 ARM (arm-gcc -O2) 编译上述代码时,我看不出汇编代码有什么不同。以下是两种情况下 ARM 程序集的输出 -likely
和unlikely
为什么编译器不针对 ARM 的情况下的分支预测进行优化?
c++ - c++20 可能和不可能的性能优化
我阅读了有关 c++20 的属性likely
和属性unlikely
,我想问一下是否有一些合理的官方数据表明这个新属性给执行带来的性能优势。
我的意思是有一些示例执行测试可以让我衡量执行代码时此功能对性能的影响有多大?
我注意到这个属性经常用于 linux 内核开发(在 C 代码中)。所以我的问题是:
编译器是否已经充分优化了代码?有有效改进性能的例子或证明吗?
对于所有类型的机器是否都是如此,或者某些架构需要可能/不太可能进行良好的改进?
编辑 :
我正在搜索向编译器展示这种建议的有效性的图表或数据。(我在网上搜索,但我没有找到任何好东西)如果有人知道一些论文,或者类似的可以回答这个问题吗?
symbols - .text.unlikely 在 ELF 目标文件中是什么意思?
在我的objdump -t
输出中,我看到以下两行:
和
我知道l
意味着本地和g
全球。我也知道这.text
是目标文件中的一个部分或一种类型的部分,包含已编译的程序指令。但什么是.text.unlikely
?假设它是不同的部分(或部分类型).text
- 有什么区别?
c++ - [[likely]] 和 [[unlikely]] 影响程序汇编的简单示例?
C++20 将属性[[likely]]
和语言引入[[unlikely]]
了语言,可用于允许编译器针对一个执行路径比其他执行路径更可能或不太可能的情况进行优化。
考虑到不正确的分支预测的代价,这似乎是一个在性能关键的代码部分中可能非常有用的功能,但我不知道它实际上会导致编译器做什么。
是否有一段简单的代码可以添加[[likely]]
和[[unlikely]]
属性更改编译器的程序集输出?也许更重要的是,这些变化有什么作用?
我创建了一个简单的示例以供自己理解,以查看程序集是否有任何差异,但似乎此示例过于简单,无法实际显示程序集的任何更改:
c++ - 使用 [[unlikely/likely]] 属性时,MSVC C++ 编译器在相同代码的不同版本上给出不一致的性能
我只是在尝试[[unlikely/likely]]
使用/std:c++latest
.
为此,我在底部使用http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0479r0.html提供的代码的修改版本Appendix A
请注意,所有编译都是在 x64 发布模式下使用/O2
最新版本的 Visual Studio 2019 (16.10.3) 和 Intel(R) Core(TM) i7-7700HQ 2.8Ghz CPU 完成的。
然后我测试了 using [[unlikely]]
,[[likely]]
并且没有属性会影响所花费的时间。
首先测试[[unlikely]]]
我发现在我的系统上运行大约需要 6750 毫秒。然后我进行了测试[[likely]]
,它也需要大约 6750 毫秒才能运行。起初我认为这可能只是因为属性是提示,因此编译器可以忽略它们。然后我进行了测试no attribute
(只是不使用[[unlikely/likely]]
),代码运行时间约为 9000 毫秒。如果编译器之前忽略了属性,那么它应该给出相同的 6750ms 时间,对吧?
然后我回去测试[[likely]]
,发现它现在运行在 ~9000 毫秒???在这一点上,我真的很困惑,所以回去检查[[unlikely]]
,发现它在 ~6750ms 内运行。再次检查[[likely]]
它现在运行在 ~6750 毫秒。
这太奇怪了,经过一些挖掘查看生成的程序集后,我发现有时生成的程序集会超过 6000 行,有时会低于 2000 行,随后编译???对于相同代码的后续编译也是如此。经过一番谷歌搜索后,我发现了一个奇怪的评论:
为什么 Godbolt 生成的 asm 输出与我在 Visual Studio 中的实际 asm 代码不同?
而现在我更加困惑了,为什么 MSVC 会生成不同的代码?
回到我的实验,我根据编译顺序发现了这些结果:
No attribute
=>[[unlikely]]
=>[[likely]]
〜9000ms =>〜6750ms =>〜6750ms并继续〜6750ms以进行后续
[[likely]]
编译并切换回[[unlikely]]
获得相同的结果,而切换回No attribute
获得〜9000ms。No attribute
=>[[likely]]
=>[[unlikely]]
~9000ms => ~9000ms => ~9000ms 和后续
[[unlikely]]
编译得到相同的 ~9000ms 结果,这在切换到时是相同的,[[likely]]
并且仅在编译后编译时表现出第一个序列中显示的行为No attribute
。
为了确保这不是一些随机的怪癖,我多次运行这些测试而不在每一步编译(只需运行从文件资源管理器生成的 .exe 文件)并获得一致的结果。我什至从每个不同的编译序列中保存了每个不同的 .exe 文件,然后再次运行它们,得到了同样奇怪的结果。
我还没有比较 .exe 字节,但我想避免这样做,因为我不太精通该领域“^-^
我错过了什么,这是一个错误吗?一切都如此不一致,这一切似乎都如此奇怪。
c++ - 我可以用我的代码改进分支预测吗?
这是一个对任何平台、语言或编译器都开放的天真的一般问题。虽然我对 Aarch64、C++、GCC 最好奇。
当在依赖于 I/O 状态(编译器无法预测)的程序流中编写一个不可避免的分支时,我知道一种状态比另一种更有可能,我如何向编译器表明这一点?
这是否更好
比这个?
如果通信协议使更可能或临界值真(高)或假(低)有帮助吗?