如果条件来自简单功能,则删除

时间:2016-01-12 15:52:56

标签: c++ optimization micro-optimization

我需要从以下两个函数中删除尽可能多的条件:

inline int inc_with_1bit_saturation(int counter)
{
    if (counter == 1)
        return --counter;
    return ++counter;
}

void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
    int counter = 0;

    for (int i = 0; i < size; ++i)
    {
        if (input[i] != counter)
        {
            counter = inc_with_1bit_saturation(counter);
            output[i] = 0;
        }
        else output[i] = 1;
    }
}

我该怎么做?if分支是绝对必要的,不能被删除,哪一个可以被简单的按位操作或类似的东西取代?

更新1

根据用户JSF的重要提示,代码现在看起来像这样:

void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
    int counter = 0;

    for (int i = 0; i < size; ++i)
    {
        if (input[i] != counter)
        {
            counter = 1 - counter;
            output[i] = 0;
        }
        else output[i] = 1;
    }
}

更新2

感谢Cantfindname,代码变成了这样:

void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
    int counter = 0;

    for (int i = 0; i < size; ++i)
    {
        output[i] = counter == input[i];
        counter = output[i] * counter + (1 - output[i])*(1 - counter);
    }
}

这完全解决了这个问题。

3 个答案:

答案 0 :(得分:6)

对于循环内的if语句:

output[i] = (int)(input[i]==counter);
counter = output[i]*counter + (1-output[i])*(1-counter) //used JSF's trick

True转换为1,false转换为0,根据:bool to int conversion

答案 1 :(得分:1)

函数inc_with_1bit_saturation相当于 modulo 2 。所以你可以替换

counter = inc_with_1bit_saturation(counter);

使用

counter = (counter+1) % 2;

答案 2 :(得分:1)

void branch_prediction_1bit_saturation(int* input, int* output, int size) {

    int counter = 0;

    for (int i = 0; i < size; ++i)
    {
        output[i] = (int)!((!!input[i]) ^ counter);
        counter = (int)((!!input[i]) & counter) | ((!!input[i]) & !counter);
    }
}

A是逻辑输入[i];

B是逻辑计数器;

输入[i]!=计数器的真值表是:

A B

0 0 | 0 - &gt; (0&amp; 0)| (0&amp;!0)= 0 | 0 = 0

0 1 | 0 - &gt; (0&amp; 1)| (0&amp;!1)= 0 | 0 = 0

1 0 | 1 - &gt; (1&amp; 0)| (1&amp;!0)= 0 | 1 = 1

1 1 | 1 - &gt; (1&amp; 1)| (1&amp;!1)= 1 | 0 = 1

输出[i]

的真值表

A B

0 0 | 1 - &gt; !(0 ^ 0)=!(0)= 1

0 1 | 0 - &gt; !(0 ^ 1)=!(1)= 0

1 0 | 0 - &gt; !(1 ^ 0)=!(1)= 0

1 1 | 1 - &gt; !(1 ^ 1)=!(0)= 1

:)