我有一个性能关键的内联函数.它根据参数生成一些数据.我希望编译器优化所有调用的数据生成,其中参数在编译时是已知的.问题是我无法强制编译器将优化数据从堆栈中放入静态常量,因为static当参数不是编译时常量时,标记数据会破坏这种情况.堆栈上的常量数据会影响性能.有没有办法推断(可能使用templates/boost :: enable_if),参数是编译时常量并选择适当的数据生成实现?
澄清
基本上我有类似以下内容:
struct Data {
int d_[16];
};
inline Data fun(int param)
{ //param can sometimes be a compile-time constant
... //generate the data
Data res = {gen0, gen2, gen3, ..., gen15}; //put the data into result
return res;
}
Run Code Online (Sandbox Code Playgroud)
所以当param不是编译时常量时,我们只生成所有数据并返回.
时param是已知的,编译器可以优化数据产生出来.但是,它无法优化以下线路并生成大量代码,只是将res成员设置为已知数据(数据嵌入到程序代码中).我希望编译器创建一个静态常量,然后将其复制到返回对象(这比执行包含嵌入数据的代码更快).由于这是内联函数,因此即使是副本也可能不是必需的.
放弃
这个问题与如何使用内联函数的不同重载不同,具体取决于编译时参数?.这是更普遍的问题.
这不是可移植的,但在 GCC 和 Clang 上可能有一个__builtin_constant_p编译器函数。这可以让您询问编译器在编译期间是否知道变量的值。你可以这样使用它:
void f(int arg) {
if (__builtin_constant_p(arg) && arg == 0) {
// Handle case where arg is 0 AND known at compile time.
} else {
// Generic code.
}
}
Run Code Online (Sandbox Code Playgroud)
这样,else如果arg在编译时已知并且为 0,编译器将不会在分支中生成代码。
使之更可移植的一个有用技巧可能是使用一些宏黑客技术。
#ifdef __GNUC__
# define CONSTANT_P(x) __builtin_constant_p(x)
#else
# define CONSTANT_P(x) 0
#endif
Run Code Online (Sandbox Code Playgroud)
根据需要添加支持与此类似的其他编译器,您现在可以使用它,而不会在不支持此功能的编译器上产生额外开销。也就是说,那些编译器,如果它们有任何价值的话,将消除CONSTANT_P分支,只留下通用代码。
| 归档时间: |
|
| 查看次数: |
300 次 |
| 最近记录: |