简体   繁体   English

在C if-else语句中,是否应该首先出现更可能的条件?

[英]In the C if-else statement, should the condition which is more likely to be true come first?

I happened to write a if-else statement, the condition would be false at most time(check a static pointer is assigned or not). 我碰巧写了一个if-else语句,条件在大多数时候都是假的(检查是否分配了静态指针)。 Which one would be better for the compiler to optimize? 编译器优化哪一个会更好? Or they are just equal?. 或者他们是平等的? The function would be called so many times, so it is critical to optimize its performance. 该函数将被调用很多次,因此优化其性能至关重要。

void foo() {
  static int * p = NULL;
  if (p == NULL) {
     p = (int *) malloc( SIZE * sizeof(int)); 
  }
  //do something here
} 

void foo() {
  static int * p = NULL;
  if (p != NULL) {
    //do something here 
  } else {
    p = (int *) malloc( SIZE * sizeof(int));  
    //do something
  }
}

Some compilers can allow the dev to specify which is condition is more likely or unlikely to occur. 一些编译器可以允许开发人员指定哪个条件更有可能或不太可能发生。 This is heavily used in the Linux kernel. 这在Linux内核中大量使用。

In gcc, there's the likely(x) or unlikely(x) macros. 在gcc中,有可能的(x)或不太可能的(x)宏。 Example: 例:

if (unlikely(p == NULL)) {
    p = malloc(10);
}

If the function is called often enough to not be evicted from the branch predictor, then the predictor will take care of everything for you, since it will learn very quickly which is the "likely" branch. 如果经常调用该函数以便不从分支预测器中逐出,则预测器将为您处理所有事情,因为它将非常快速地学习哪个是“可能的”分支。

Some compilers allow you to decorate conditionals with prediction hints. 一些编译器允许您使用预测提示来装饰条件。 Check your vendor's documentation, and add a hint if you can. 检查供应商的文档,如果可以,请添加提示。

Specific platforms document the default predictor behaviour (eg see the Intel Optimization Manual for x86), but it's best left to your compiler to implement that via the aforementioned hints. 特定平台记录了默认的预测器行为(例如,参见x86的英特尔优化手册),但最好由编译器通过上述提示实现。 In fact, you don't really have a choice, since you don't control your compilers code generation anyway, so the only last measure left to you would be to write the code in machine code yourself and implement the platform's advice on default prediction. 事实上,你真的没有选择,因为你无论如何都不能控制你的编译器代码生成,所以留给你的唯一最后一个措施是自己编写机器代码中的代码并实现平台对默认预测的建议。

At the end, it depends on the compiler and the optimization it does, which changes from compiler version, processor, compiler family... 最后,它取决于编译器和它的优化,它从编译器版本,处理器,编译器系列改变...

My rule of thumb on this kind of subjects is to check on your actual platform by doing some extensive profiling. 我对这类主题的经验法则是通过进行一些广泛的分析来检查你的实际平台。 I usually also follow the rule "code first correctly, optimize later only if required". 我通常也遵循规则“首先正确编码,仅在需要时进行优化”。 Trying to optimize upfront often leads to less readable code and design (and sometime, not even better performance). 尝试预先优化通常会导致代码和设计的可读性降低(有时甚至没有更好的性能)。

Conditions are checked in order from left to right, this is in the C standard, thus allowing for conditionals like 条件从左到右按顺序检查,这是在C标准中,因此允许条件类似

if( ptr != NULL && ptr->member == value )

This also means that it makes sense to place the condition which is most likely to be false first. 这也意味着首先放置最可能是错误的条件是有意义的。

http://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx http://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx

If you looking for performance I wouldn't use malloc at all. 如果你在寻找性能,我根本就不会使用malloc。 Get Huge chunk of RAM and use it directly without allocation deallocation wrappers. 获取大量的RAM并直接使用它而无需分配释放包装器。 Also consider using macros code will be bigger but performance also will increase. 另外考虑使用宏代码会更大但性能也会提高。

#define ASSURE_PTR(a)      if (!a){ \
        a = (int *) malloc (SIZE * sizeof(int)); \
    }

If the function gets called often, any decent branch predictor would learn to predict the common path very quickly. 如果经常调用函数,任何体面的分支预测器都会学会很快地预测公共路径。 Note that the code may be compiled differently than you expect since some compilers rely on static branch prediction , and may recognize this pattern. 请注意,代码的编译方式可能与您预期的不同,因为某些编译器依赖于静态分支预测 ,并且可能会识别此模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM