Вы можете использовать условное перемещение или для выбора целого числа без ответвлений , чтобы назначить b1 без оператора if:
// if a >= 0, return x, else y
// assumes 32-bit processors
inline int isel( int a, int x, int y ) // inlining is important here
{
int mask = a >> 31; // arithmetic shift right, splat out the sign bit
// mask is 0xFFFFFFFF if (a < 0) and 0x00 otherwise.
return x + ((y - x) & mask);
};
// ...
while(x < s)
{
b1 = isel( x + b - s, s-x, b1 );
SendData(x, b1); /*SendData(offset,length);*/
x += b1;
}
Это только полезная оптимизация на процессорах по порядку. Это не будет иметь никакого значения на современном ПК x86, который имеет быстрое отделение и модуль переупорядочения. Это может быть полезно в некоторых встроенных системах (таких как Playstation), где задержка конвейера имеет большее значение для производительности, чем количество команд. Я использовал его, чтобы сбрить несколько микросекунд в плотных петлях.
Теоретически, компилятор "должен" иметь возможность превращать троичное выражение (b = (a > 0 ? x : y)
) в условный ход, но я никогда не встречал такого, который это делал.
Конечно, в более широком смысле все, кто говорит, что это бессмысленная оптимизация по сравнению со стоимостью SendData()
, верны. Разница между cmov и веткой составляет около 4 наносекунд, что незначительно по сравнению со стоимостью сетевого вызова. Тратить свое время на исправление этой ветки, которая происходит один раз за сетевой вызов, - все равно что ехать по городу, чтобы сэкономить 1%; на бензине.