gpt4 book ai didi

c++ - 混合常量/非常量三元运算符的编译时

转载 作者:搜寻专家 更新时间:2023-10-31 01:13:22 25 4
gpt4 key购买 nike

考虑以下示例:

template<int X> class MyClass
{
public:
MyClass(int x) {_ncx = x;}
void test()
{
for (unsigned int i = 0; i < 1000000; ++i) {
if ((X < 0) ? (_cx > 5) : (_ncx > 5)) {
/* SOMETHING */
} else {
/* SOMETHING */
}
}
}
protected:
static const int _cx = (X < 0) ? (-X) : (X);
int _ncx;
};

我的问题是:MyClass<-6>::test() 和 MyClass<6>::test() 会有不同的速度吗?

我希望如此,因为在模板参数为负的情况下,测试函数中的 if 可以在编译时求值,但我不确定如果存在,编译器的行为是什么是三元运算符中的编译时事物和非编译时事物(这里就是这种情况)。

注意:这是一个纯粹的“理论”问题。如果"is"的概率非空,我将使用此类编译时模板参数为我的代码实现一些类,如果没有,我将只提供运行时版本。

最佳答案

对于我的编译器(OS X 上的 clang++ v2.9)编译这段相似但不相同的代码:

void foo();
void bar();

template<int N>
void do_something( int arg ) {
if ( N<0 && arg<0 ) { foo(); }
else { bar(); }
}

// Some functions to instantiate the templates.
void one_fn(int arg) {
do_something<1>(arg);
}

void neg_one_fn(int arg) {
do_something<-1>(arg);
}

这将使用 clang++ -S -O3 生成以下程序集。

one_fn = do_something<1>

第一个函数汇编显然只有对 bar 的调用。

    .globl  __Z6one_fni
.align 4, 0x90
__Z6one_fni: ## @_Z6one_fni
Leh_func_begin0:
pushl %ebp
movl %esp, %ebp
popl %ebp
jmp __Z3barv ## TAILCALL
Leh_func_end0:

neg_one_fn = do_something<-1>

第二个函数已简化为一个简单的 if 调用 barfoo

    .globl  __Z10neg_one_fni
.align 4, 0x90
__Z10neg_one_fni: ## @_Z10neg_one_fni
Leh_func_begin1:
pushl %ebp
movl %esp, %ebp
cmpl $0, 8(%ebp)
jns LBB1_2 ## %if.else.i
popl %ebp
jmp __Z3foov ## TAILCALL
LBB1_2: ## %if.else.i
popl %ebp
jmp __Z3barv ## TAILCALL
Leh_func_end1:

总结

所以你可以看到编译器内联了模板,然后在可能的时候优化掉了分支。因此,您希望的那种转换确实发生在当前的编译器中。我也从旧的 g++ 4.0.1 编译器得到了类似的结果(但汇编不太清晰)。

附录:

我认为这个示例与您的初始案例不太相似(因为它不涉及三元运算符)所以我将其更改为:(获得相同类型的结果)

template<int X>
void do_something_else( int _ncx ) {
static const int _cx = (X<0) ? (-X) : (X);
if ( (X < 0) ? (_cx > 5) : (_ncx > 5)) {
foo();
} else {
bar();
}
}

void a(int arg) {
do_something_else<1>(arg);
}

void b(int arg) {
do_something_else<-1>(arg);
}

这生成程序集

a() = do_something_else<1>

这仍然包含分支。

__Z1ai:                                 ## @_Z1ai
Leh_func_begin2:
pushl %ebp
movl %esp, %ebp
cmpl $6, 8(%ebp)
jl LBB2_2 ## %if.then.i
popl %ebp
jmp __Z3foov ## TAILCALL
LBB2_2: ## %if.else.i
popl %ebp
jmp __Z3barv ## TAILCALL
Leh_func_end2:

b() = do_something_else<-1>

分支被优化掉了。

__Z1bi:                                 ## @_Z1bi
Leh_func_begin3:
pushl %ebp
movl %esp, %ebp
popl %ebp
jmp __Z3barv ## TAILCALL
Leh_func_end3:

关于c++ - 混合常量/非常量三元运算符的编译时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12592588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com