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
}
精彩评论