避免循环中的条件和函数调用 [英] Avoiding conditionals and function invocations inside a loop

查看:156
本文介绍了避免循环中的条件和函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下代码:

void function(int parameter)
{
  for( ... ) // a big loop
  {
    double a = ...;
    for( ... ) // a big loop
    {
      double b = ...;

      double value;
      if(parameter == 1)
        value = some_math_expression_1(a, b);
      else if(parameter == 2)
        value = some_math_expression_2(a, b);
      ...
    }
  }
}

这个想法是,根据参数,我想对 a b 应用一些数学表达式。这个函数执行多次,并且必须快速,我不知道在每次迭代的条件分支是否可以引入一个我可以节省的开销。

The idea is that depending on the parameter I want to apply some math expression to a and b. This function is executed many times and must be fast, and I wonder if those conditional branches at each iteration can introduce an overhead that I could save.

现在,我写了如下代码:

Right now, I have written the code like this:

void function(int parameter)
{
  if(parameter == 1)
    function1();
  else if(parameter == 2)
    function2();
  else
    ...
}

如果我在每个 functionX()中重复代码,则直接应用数学表达式。明显的问题是,当我想改变一些代码,我必须做它几次(我现在有大约10个数学表达式)。

So that I can apply the math expression directly if I repeat the code in every functionX(). The obvious problem is that when I want to change some piece of code I have to do it several times (I have around 10 math expressions now).

我可以使用什么方法避免 function 中的任何开销?

What approach could I use to avoid any overhead in function?

如果我传递一个指向函数 some_math_expression_X 函数(我会更改函数调用的条件)?

What if I pass a pointer to functions some_math_expression_X to function (I would change the conditionals for function invocations)?

如果我将整个函数编码为宏(uf)并将数学表达式设置为参数怎么办?

What if I code the whole function as a macro (uf) and set the math expression as a parameter?

如果我使用模板并将数学表达式作为指向内联函数的指针传递(这是可能的),该怎么办?

What if I use a template and pass the math expression as a pointer to an inline function (is this even possible)?

编辑:感谢您的回答。我知道我可以使用你提出的方法(指向/数组的函数,或依靠分支预测器)。但是,你有一些洞察,什么将是更好的避免开销?数学表达式很简单(类似 a * b ),除了长整型的循环之外, function

EDIT: Thank you for your answers. I know I can use the methods you are proposing (pointers to / array of functions, or relying on the branch predictor). However, do you have some insight about what would be better in terms of avoiding overhead? The math expressions are quite simple (something like a*b), and in addition to the loops that are long, function is also called many times (do branch predictions "survive" between calls?).

推荐答案

您可以将函数转换为模板:

You can convert the function into a template:

void functionT<int PARAMETER>()
{
  for( ... ) // a big loop
  {
    double a = ...;
    for( ... ) // a big loop
    {
      double b = ...;

      double value;
      if(PARAMETER == 1) //Constant condition!!!
        value = some_math_expression_1(a, b);
      else if(PARAMETER == 2)  //Constant condition!!!
        value = some_math_expression_2(a, b);
      ...
    }
  }
}

由于条件总是真或总是假,编译器将优化条件树并留下只有真实的数学表达式。没有分支,也没有函数调用!

Since the conditions are always true or always false, the compiler will optimize the condition tree away and leave only the real math expression. No branches and no function calls!

现在,只能使用常量参数:

Now, you can use it only with constant parameters:

functionT<1>();

但不适用于变量:

int x = 1;
functionT<x>(); //Error

如果需要,您可以创建一个包装器:

If you need that, you can make a wrapper:

void function(int parameter)
{
    switch (parameter)
    {
        case 1: functionT<1>(); break;
        case 2: functionT<2>(); break;
    }
}

这篇关于避免循环中的条件和函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆