开发者

Optimizing the loop in a block by block transfer

In the below code, is there a way to avoid the if statement?

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

Thanks much!


I don't know maybe you'll think:

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);

is better?


Don't waste your time on pointless micro-optimizations your compiler probably does for you anyway.

Program for the programmer; not the computer. Compilers get better and better, but programmers don't.

If it makes your program more readable (@PaulPRO's answer), then do it. Otherwise, don't.


You can use a conditional move or branchless integer select to assign b1 without an if-statement:

// 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;
}

This is only a useful optimization on in-order processors, though. It won't make any difference on a modern PC's x86, which has a fast branch and a reorder unit. It might be useful on some embedded systems (like a Playstation), where pipeline latency matters more for performance than instruction count. I've used it to shave a few microseconds in tight loops.

In theory a compiler "should" be able to turn a ternary expression (b = (a > 0 ? x : y)) into a conditional move, but I've never met one that did.

Of course, in a larger sense everyone who says that this is a pointless optimization compared to the cost of SendData() is correct. The difference between a cmov and a branch is about 4 nanoseconds, which is negligible compared to the cost of a network call. Spending your time fixing this branch which happens once per network call is like driving across town to save 1¢ on gasoline.


If you try to remove if(), it might change your logic and you have to spend lot of time for testing. I see only one potential change:

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
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜