gpt4 book ai didi

c++ - gcc 会根据条件优化我的循环吗?

转载 作者:可可西里 更新时间:2023-11-01 16:26:03 26 4
gpt4 key购买 nike

我有以下循环:

//condition will be set here to true or false

for (int i = 0; i < LARGE_NUMBER; i++) {
if (condition) {
//do foo
} else {
//do bar
}
}

假设:一个循环如果没有条件比有条件更快。 (这是真的?)问题:如果 condition 已设置在 for 循环之外,并且循环本身没有触及 condition,gcc 是否会分解出我的 if

如果不是,我应该切换iffor,重复代码,违反DRY等。

最佳答案

对于那些不想阅读冗长文章的人,此优化称为(在 LLVM 中)Loop Unswitch .

为什么不问问编译器?

void foo(char* c);

int main(int argc, char **argv) {
bool const condition = argc % 2;

for (int i = 0; i != argc; ++i) {
if (condition) {
foo(argv[1]);
} else {
foo(argv[0]);
}
}
return 0;
}

转换为 SSA 形式(通过 LLVM try out ):

define i32 @main(i32 %argc, i8** nocapture %argv) {
entry:
%0 = icmp eq i32 %argc, 0 ; <i1> [#uses=1]
br i1 %0, label %bb5, label %bb.nph

bb.nph: ; preds = %entry
%1 = and i32 %argc, 1 ; <i32> [#uses=1]
%toBool = icmp eq i32 %1, 0 ; <i1> [#uses=1]
%2 = getelementptr inbounds i8** %argv, i64 1 ; <i8**> [#uses=1]
br i1 %toBool, label %bb3.us, label %bb3

bb3.us: ; preds = %bb3.us, %bb.nph
%i.07.us = phi i32 [ %4, %bb3.us ], [ 0, %bb.nph ] ; <i32> [#uses=1]
%3 = load i8** %argv, align 8 ; <i8*> [#uses=1]
tail call void @_Z3fooPc(i8* %3)
%4 = add nsw i32 %i.07.us, 1 ; <i32> [#uses=2]
%exitcond = icmp eq i32 %4, %argc ; <i1> [#uses=1]
br i1 %exitcond, label %bb5, label %bb3.us

bb3: ; preds = %bb3, %bb.nph
%i.07 = phi i32 [ %6, %bb3 ], [ 0, %bb.nph ] ; <i32> [#uses=1]
%5 = load i8** %2, align 8 ; <i8*> [#uses=1]
tail call void @_Z3fooPc(i8* %5)
%6 = add nsw i32 %i.07, 1 ; <i32> [#uses=2]
%exitcond8 = icmp eq i32 %6, %argc ; <i1> [#uses=1]
br i1 %exitcond8, label %bb5, label %bb3

bb5: ; preds = %bb3, %bb3.us, %entry
ret i32 0
}

可能不太可读,所以让我指出这里的内容:

  • entry:检查argc是否等于0,如果是,则转到bb5(退出),否则转到 bb.nph
  • bb.nph:计算condition的值,如果为真,则转到bb3.us,否则转到bb3
  • bb3.usbb3:分别为真假条件循环
  • bb5:退出

只要效果与您要求的相似,编译器几乎可以按照它想要的方式转换您的代码。在这种情况下,它有效地将代码重写为:

int main(int argc, char**argv) {
if (argc != 0)
{
int i = 0;
if (argc % 2) {
do {
foo(argv[1]);
++i;
} while (i != argc);
} else {
do {
foo(argv[0]);
++i;
} while (i != argc);
}
}
return 0;
}

这是循环不变优化的一种形式,在这里结合了第一次检查以避免在循环不会被执行时计算条件。

对于我们当中那些认为第一个解决方案更清晰的人来说,我们很高兴让编译器为我们进行细节优化!

关于c++ - gcc 会根据条件优化我的循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5522913/

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