visual-studio MSVC 的可能/不太可能等效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1440570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
likely/unlikely equivalent for MSVC
提问by Franck Freiburger
GCC compiler supports __builtin_expect statement that is used to define likely and unlikely macros.
GCC 编译器支持用于定义可能和不可能的宏的 __builtin_expect 语句。
eg.
例如。
#define likely(expr) (__builtin_expect(!!(expr), 1))
#define unlikely(expr) (__builtin_expect(!!(expr), 0))
Is there an equivalent statement for the Microsoft Visual C compiler, or something equivalent ?
是否有 Microsoft Visual C 编译器的等效语句或等效语句?
采纳答案by DigitalRoss
I say just punt
我说只是平底船
There is nothing like it. There is __assume(), but don't use it, it's a different kind of optimizer directive.
没什么东西跟它一样了。有__assume(),但不要使用它,它是一种不同的优化器指令。
Really, the reason the gnu builtin is wrapped in a macro is so you can just get rid of it automatically if __GNUC__is not defined. There isn't anything the least bit necessary about those macros and I bet you will not notice the run time difference.
真的,gnu 内置函数被包裹在宏中的原因是,如果__GNUC__未定义,您可以自动摆脱它。这些宏没有任何必要,我敢打赌您不会注意到运行时间差异。
Summary
概括
Just get rid of (null out) *likelyon non-GNU. You won't miss it.
只需*likely在非 GNU 上摆脱(null out)即可。你不会错过的。
回答by Gene
According to http://www.akkadia.org/drepper/cpumemory.pdf(page 57), it still makes sense to use static branch prediction even if CPU predicts correctly dynamically. The reason for that is that L1i cache will be used even more efficiently if static prediction was done right.
根据http://www.akkadia.org/drepper/cpumemory.pdf(第 57 页),即使 CPU 动态正确预测,使用静态分支预测仍然有意义。这样做的原因是,如果静态预测正确,L1i 缓存的使用效率将更高。
回答by Pauli Nieminen
C++20 standard will include [[likely]]and [[unlikely]]branch prediction attributes.
C++20 标准将包括[[likely]]和[[unlikely]]分支预测属性。
The latest revision of attribute proposal can be found from http://wg21.link/p0479
属性提议的最新版本可以从http://wg21.link/p0479找到
The original attribute proposal can be found from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0479r0.html
原始属性提案可以从http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0479r0.html找到
Programmers should prefer PGO. Attributes can easily reduce performance if applied incorrectly or they later become incorrect when program changes.
程序员应该更喜欢 PGO。如果应用不当,属性很容易降低性能,或者在程序更改时它们会变得不正确。
回答by Vyacheslav Lanovets
According to Branch and Loop Reorganization to Prevent Mispredictsdocument from Intel:
根据英特尔的分支和循环重组以防止错误预测文件:
In order to effectively write your code to take advantage of these rules, when writing if-else or switch statements, check the most common cases first and work progressively down to the least common.
为了有效地编写代码以利用这些规则,在编写 if-else 或 switch 语句时,首先检查最常见的情况,然后逐步减少到最不常见的情况。
Unfortunately you cannot write something like
不幸的是你不能写类似的东西
#define if_unlikely(cond) if (!(cond)); else
because MSVC optimizer as of VS10 ignores such "hint".
因为从 VS10 开始,MSVC 优化器会忽略此类“提示”。
As I prefer to deal with errors first in my code, I seem to write less efficient code. Fortunately, second time CPU encounters the branch it will use its statistics instead of a static hint.
由于我更喜欢在代码中首先处理错误,因此我编写的代码效率较低。幸运的是,CPU 第二次遇到分支时,它将使用其统计信息而不是静态提示。
回答by Michael
__assumeshould be similar.
__assume应该是相似的。
However, if you want to do this really well you should use Profile Guided Optimizationrather than static hints.
但是,如果您想真正做到这一点,您应该使用Profile Guided Optimization而不是静态提示。
回答by nemequ
I know this question is about Visual Studio, but I'm going to try to answer for as many compilers as I can (including Visual Studio)…
我知道这个问题是关于 Visual Studio 的,但我将尝试回答尽可能多的编译器(包括 Visual Studio)......
A decade later there is progress! As of Visual Studio 2019 MSVC still doesn't support anything like this (even though it's the most popular builtin/intrinsic), but as Pauli Nieminen mentioned above C++20 has likely/ unlikelyattributeswhich can be used to create likely/unlikely macros and MSVC usually adds support for new C++ standards pretty quickly (unlike C) so I expect Visual Studio 2021 to support them.
十年后有进步!到 Visual Studio 2019 MSVC 仍然不支持这样的东西(即使它是最流行的内置/内部),但正如 Pauli Nieminen 上面提到的,C++20 具有likely/unlikely属性,可用于创建可能/不可能的宏和MSVC 通常会很快添加对新 C++ 标准的支持(与 C 不同),因此我希望 Visual Studio 2021 能够支持它们。
Currently (2019-10-14) only GCC supports these attributes, and even then only applied to labels, but it is sufficient to at least do some basic testing. Here is a quick implementation which you can test on Compiler Explorer:
目前 (2019-10-14) 只有 GCC 支持这些属性,即使那时也只应用于标签,但至少做一些基本的测试就足够了。这是您可以在 Compiler Explorer 上测试的快速实现:
#define LIKELY(expr) \
( \
([](bool value){ \
switch (value) { \
[[likely]] case true: \
return true; \
[[unlikely]] case false: \
return false; \
} \
}) \
(expr))
#define UNLIKELY(expr) \
( \
([](bool value){ \
switch (value) { \
[[unlikely]] case true: \
return true; \
[[likely]] case false: \
return false; \
} \
}) \
(expr))
You'll probably want to #ifdef around it to support compilers that can't handle it, but luckily most compilers support __builtin_expect:
您可能希望在它周围使用 #ifdef 以支持无法处理它的编译器,但幸运的是大多数编译器都支持__builtin_expect:
- GCC 3.0
- clang
- ICC since at least 13, probably much longer.
- Oracle Development Studio 12.6+, but only in C++ mode.
- ARM 4.1
- IBM XL C/C++ since at least 10.1, probably longer.
- TI since 6.1
- TinyCC since 0.9.27
- 海湾合作委员会 3.0
- 铛
- ICC 至少 13 年以来,可能更长。
- Oracle Development Studio 12.6+,但仅限于 C++ 模式。
- ARM 4.1
- IBM XL C/C++ 至少从 10.1 开始,可能更长。
- TI 从 6.1 开始
- 从 0.9.27 开始的 TinyCC
GCC 9+ also supports __builtin_expect_with_probability. It's not available anywhere else, but hopefully one day… It takes a lot of the guesswork out of trying to figure out whether to use ilkely/unlikely or not—you just set the probability and the compiler (theoretically) does the right thing.
GCC 9+ 还支持__builtin_expect_with_probability. 它在其他任何地方都不可用,但希望有朝一日......试图弄清楚是否使用 ilkely/unlikely 需要大量猜测——您只需设置概率,编译器(理论上)就会做正确的事情。
Also, clang supports a __builtin_unpredictable(since 3.8, but test for it with __has_builtin(__builtin_unpredictable)). Since a lot of compilers are based on clang these days it probably works in them, too.
此外,clang 支持 a __builtin_unpredictable(自 3.8 起,但使用 对其进行测试__has_builtin(__builtin_unpredictable))。由于现在很多编译器都基于 clang,因此它可能也适用于它们。
If you want this all wrapped up and ready to go, you might be interested in one of my projects, Hedley. It's a single public-domain C/C++ header which works on pretty much all compilers and contains lots of useful macros, including HEDLEY_LIKELY, HEDLEY_UNLIKELY, HEDLEY_UNPREDICTABLE, HEDLEY_PREDICT, HEDLEY_PREDICT_TRUE, and HEDLEY_PREDICT_FALSE. It doesn't have the C++20 version quite yet, but it should be there soon…
如果您希望这一切都结束并准备就绪,您可能会对我的一个项目Hedley感兴趣。这是一个公共领域的C / C ++头,其适用于几乎所有的编译器,并包含了许多有用的宏,包括HEDLEY_LIKELY,HEDLEY_UNLIKELY,HEDLEY_UNPREDICTABLE,HEDLEY_PREDICT,HEDLEY_PREDICT_TRUE,和HEDLEY_PREDICT_FALSE。它还没有 C++20 版本,但应该很快就会出现……
Even if you don't want to use Hedley in your project, you might want to check the the implementations there instead of relying on the lists above; I'll probably forget to update this answer with new information, but Hedley should always be up-to-date.
即使你不想在你的项目中使用 Hedley,你也可能想检查那里的实现而不是依赖上面的列表;我可能会忘记用新信息更新这个答案,但 Hedley 应该始终是最新的。

