从简单函数中删除 if 条件
Remove if conditions from simple function
我需要从以下两个函数中删除尽可能多的 if 条件:
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);
}
}
这就完全解决了这个问题。
函数inc_with_1bit_saturation
等价于模2。所以你可以替换
counter = inc_with_1bit_saturation(counter);
有
counter = (counter+1) % 2;
对于循环内的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
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] != 计数器的真相table是:
A B
0 0 | 0 --> (0 & 0) | (0 &!0) = 0 | 0 = 0
0 1 | 0 --> (0 & 1) | (0 &!1) = 0 | 0 = 0
1 0 | 1 --> (1 & 0) | (1 &!0) = 0 | 1 = 1
1 1 | 1 --> (1 & 1) | (1 & !1) = 1 | 0 = 1
输出的真相table[i]
A B
0 0 | 1 --> !(0 ^ 0) = !(0) = 1
0 1 | 0 --> !(0 ^ 1) = !(1) = 0
1 0 | 0 --> !(1 ^ 0) = !(1) = 0
1 1 | 1 --> !(1 ^ 1) = !(0) = 1
:)
我需要从以下两个函数中删除尽可能多的 if 条件:
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);
}
}
这就完全解决了这个问题。
函数inc_with_1bit_saturation
等价于模2。所以你可以替换
counter = inc_with_1bit_saturation(counter);
有
counter = (counter+1) % 2;
对于循环内的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
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] != 计数器的真相table是:
A B
0 0 | 0 --> (0 & 0) | (0 &!0) = 0 | 0 = 0
0 1 | 0 --> (0 & 1) | (0 &!1) = 0 | 0 = 0
1 0 | 1 --> (1 & 0) | (1 &!0) = 0 | 1 = 1
1 1 | 1 --> (1 & 1) | (1 & !1) = 1 | 0 = 1
输出的真相table[i]
A B
0 0 | 1 --> !(0 ^ 0) = !(0) = 1
0 1 | 0 --> !(0 ^ 1) = !(1) = 0
1 0 | 0 --> !(1 ^ 0) = !(1) = 0
1 1 | 1 --> !(1 ^ 1) = !(0) = 1
:)