开发者

Rewriting for loop efficiently, C

I want to use a byte variable i to execute a bit of code 开发者_如何学Go256 times. The line below loops indefinitely, is there a tidy alternative that would work?

for (i = 0; i < 255; i++){

Hopefully without using:

  • a 16 bit variable, (or any extra bits at all)
  • nested loops
  • while(1)
  • break; statements

Thanks


i = 0;
do {
  f(i);
} while(i++!=255);


Could always do this:

for (i = 0; i != 255; ++i)
{
    f(i);
}
f(255);

Honestly though, you'd be best just using an int. It's not going to be faster if you use an 8-bit integer. It's going to be in a register anyway.


uint8_t i = 0;
do {
    ...
} while ((++i) != 0);

Of course the assumption is that i will overflow. That's not guaranteed by C standard, yet almost always happen when the compiler does not optimize too heavily.


I would say unrolling the loop would be the most obvious way out of this one:

uint8_t i = 0;
for ( i = 0; i < 32; i++ )
{
    printf("Instance of loop %d\n", (8*i)+0);
    printf("Instance of loop %d\n", (8*i)+1);
    printf("Instance of loop %d\n", (8*i)+2);
    printf("Instance of loop %d\n", (8*i)+3);
    printf("Instance of loop %d\n", (8*i)+4);
    printf("Instance of loop %d\n", (8*i)+5);
    printf("Instance of loop %d\n", (8*i)+6);
    printf("Instance of loop %d\n", (8*i)+7);
}

In theory, this should also be quicker, since you have fewer tests and jumps. You could unroll more severely than this too, if needed.

You may also be interested in Duff's device (SO question explaining it), which would allow you to unroll any sized loop, not just one with nice factors. There are of course limits as it requires you store in memory the count of what you need, which in this case exceeds the 8-bit field, but, for the purposes of looping, say 137 times, it would come in useful.

Note you don't need to do the 8*i+1 stages, that's just to verify that enough events have happened.

Another note: "but I don't want to write my code 8 times!" can be overcome with the use of inline functions (C99) or macros (C89) as necessary.


If "byte" is char it will always be <255 on systems where char is signed (and 8 bits). If you must use a "byte" type, try unsigned char, which should work for your loop.

If it is not just an experiment, use int instead.


The only way I can think of would be to have a boolean

b = 1;
for(i = 0; i != 0 || b; i++)
{
    b = 0;
    ...
}

Or you could use a short instead, which is 2x the size of a byte.

What's happening is that the maximum unsigned byte value is 255. I'm not sure what happens with unsigned bytes, but signed bytes become negative when you overflow.


It will in general be quickest to declare i as an int. I can't imagine why you want to loop with an 8 bit integer. Perhaps you think it will be quicker than int but it won't.


EDIT: I get it wrong, it loops 255 times... :) A do-while construct is better:

  i = 0;
  do {
     // act
     i++;
  } while(i > 0);

The following two snippets loop 255 times, from 1 to 255.

  for(i = 1; i <= 255 && i != 0; i++)

should go. Or maybe

   for(i = 1; i > 0; i++)
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜