我有一个自定义的 ASSERT(...)
宏,我在 C++ 应用程序中使用它。
#include <stdlib.h>
#include <iostream>
/// ASSERT(expr) checks if expr is true. If not, error details are logged
/// and the process is exited with a non-zero code.
#ifdef INCLUDE_ASSERTIONS
#define ASSERT(expr) \
if (!(expr)) { \
char buf[4096]; \
snprintf (buf, 4096, "Assertion failed in \"%s\", line %d\n%s\n", \
__FILE__, __LINE__, #expr); \
std::cerr << buf; \
::abort(); \
} \
else // This 'else' exists to catch the user's following semicolon
#else
#define ASSERT(expr)
#endif
最近我在阅读一些 Linux 内核模块代码,发现存在 likely(...)
和 unlikely(...)
宏。这些向 CPU 提供了一个提示,即给定分支更有可能发生,并且管道应该针对该路径进行优化。
根据定义,断言的计算结果为 true(即 likely
)。
我可以在我的 ASSERT
宏中提供类似的提示吗?这里的底层机制是什么?
显然我会衡量性能上的任何差异,但理论上它应该有什么不同吗?
我只在 Linux 上运行我的代码,但我想知道是否也有跨平台的方式来执行此操作。我也在使用 gcc,但也想支持 clang。
最佳答案
性能提升不太可能显着,但这就是定义这些 linux 内核宏的方式:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
因此,您可以像这样修改您的条件(假设 expr
预期为真,因此 !(expr)
预期为假):
if (__builtin_expect(!(expr), 0)) {
或者您可以定义与内核相同的宏并使用它们以获得更好的可读性。
这是 gcc 内置的,所以当然不可移植。
This表明 clang 也支持内置函数。否则,您可以在不支持内置函数的编译器上使用上述宏并有条件地定义它们,例如 #define possible(x) (x)
。
在您的情况下,预测将是好的(或者您正在中止),所以不应该有悲观的风险,但是如果您确实考虑更广泛地使用内置函数,这里有一句话来自 gcc 文档的建议:
In general, you should prefer to use actual profile feedback for this (-fprofile-arcs), as programmers are notoriously bad at predicting how their programs actually perform.
关于c++ - 断言中的分支预测提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23910399/