Оптимизация цикла в блоке путем передачи блока - PullRequest
0 голосов
/ 20 июля 2011

В приведенном ниже коде есть ли способ избежать оператора if?

s = 13;   /*Total size*/
b = 5;    /*Block size*/
x = 0;
b1 = b;
while(x < s)
{
    if(x + b > s)
        b1 = s-x;
    SendData(x, b1);   /*SendData(offset,length);*/
    x += b1;
}

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 20 июля 2011

Не знаю, может быть, вы подумаете:

s = 13;   /*Total size*/
b = 5;    /*Block size*/
x = 0;
while(x + b < s)
{
    SendData(x, b);   /*SendData(offset,length);*/
    x += b;
}
SendData(x, s%b);

лучше?

1 голос
/ 20 июля 2011

Не тратьте свое время на бессмысленные микрооптимизации, которые ваш компилятор, вероятно, сделает для вас в любом случае.

Программа для программиста;не компьютер.Компиляторы становятся все лучше и лучше, а программисты - нет.

Если это делает вашу программу более читабельной (ответ @ PaulPRO), то сделайте это.Иначе не надо.

0 голосов
/ 20 июля 2011

Вы можете использовать условное перемещение или для выбора целого числа без ответвлений , чтобы назначить 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%; на бензине.

0 голосов
/ 20 июля 2011

Если вы попытаетесь удалить if(), это может изменить вашу логику, и вам придется тратить много времени на тестирование. Я вижу только одно потенциальное изменение:

s = 13;
b = 5;
x = 0;
b1 = b;
while(x < s)
{
  const unsigned int total = x + b;  // <--- introduce 'total' 
  if(total > s)
    b1 = s-x;
  SendData(x, b1);
  x = total;   // <--- reusing it
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...