【问题标题】:What's considered to be compile time branching ? [duplicate]什么被认为是编译时分支? [复制]
【发布时间】:2014-09-23 05:16:31
【问题描述】:

提供编译时分支的技术/c++ 语言工具-特性有哪些?


第一次尝试枚举它们(我期待添加更正):

  1. 重载解决方案:例如选择“最佳”版本适合提供的参数

    void F(X& arg);
    void F(X&& arg); 
    
  2. 模板专业化:创建为“特殊参数”运行的代码——一种对模板元编程和编译时递归至关重要的技术

    template<int N> struct A    { /* implementation */ };
    template<>      struct A<0> { /* specific  code */ };
    
  3. SFINAE 和表达式 sfinae:(1) 的一个特例,它提供了条件接口的工具。

    template<class C, class F>
    auto test(C c, F f) -> decltype((c->*f)(), void()); // 'C' is pointer type
    

【问题讨论】:

  • 一个带有编译时表达式的简单if 语句怎么样?
  • SFINAE 更多的是编译时布尔表达式,而不是编译时分支。
  • @NPE: 我不认为if 语句可以被认为是编译时分支,因为if 的两个分支都需要编译,即使if 有一个常量表达式参数。
  • @Mankarse 一般来说是的,但是在优化的构建中,可以消除死代码。
  • 编译时可以使用条件运算符:int b[17 &gt;= 12 ? 2 : 4];.

标签: c++ templates c++11 template-meta-programming overload-resolution


【解决方案1】:

您可以使用模板布尔参数来消除运行时分支(在发布构建中消除了死代码)。

template <bool computeMaxNorm = false>
bool CheckConvergence() {

    if (computeMaxNorm) this->residual_max_norm = 0;

    for (size_t i = 0, I = this->X.Count(); i < I; ++i) {
        double abs_res = abs(this->F_X[i]);
        if (abs_res > this->convergenceCriterion) {
            this->isConverged = false;
            if (!computeMaxNorm) return false;
        }
        if (computeMaxNorm) {
            if (abs_res > this->residual_max_norm) this->residual_max_norm = abs_res;
        }
    }
    return this->isConverged = true;
}

problem.CheckConverge&lt;false&gt;() 将比problem.CheckConverge&lt;true&gt;() 更快,并且此功能不会花费运行时分支。

但是 CPU 分支预测器通常非常好,编译时分支可能没有区别。

【讨论】:

  • 我做了一些与此非常相似的代码,并检查了输出二进制文件。删除了if,并生成了两个单独的函数。一种用于true,一种用于false
  • 是的,我倾向于滥用它,将多个模板参数与标准参数混合在一起。这使您有两组默认参数。但这可能是一种不好的做法?
【解决方案2】:

虽然不是严格的编译时分支,但您可以添加为第四个选项:

4) C++

  #if SOMETHING
    ...
  #else
    ...
  #endif

【讨论】:

  • 这是预处理器时间 - 实际上是文本替换
  • 是的,我说的不是严格的编译时间,但预处理是编译过程的一部分。
  • 编译器启动after预处理器(如果我们按照你说的方式看待它,那么链接也在编译过程中)
  • @NikosAthanasiou 在您的问题中,您说“编译时间”预处理是编译时间(即,它发生在编译过程中),链接也在编译过程中发生。
  • @NikosAthanasiou:严格来说,翻译的所有九个阶段都被标准平等对待。尽管其中只有 一些 是“编译”,但它们都可能对元编程有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2014-03-04
  • 2016-03-13
  • 2021-10-23
  • 1970-01-01
  • 2014-03-26
  • 2011-08-13
相关资源
最近更新 更多