Sign in to follow this  
waZim

What does the following code do and why would anyone write something like that?

Recommended Posts

waZim    100
What does the following code do and why would anyone write something like that?
void send (int *to, int * from, int count)
{
	int n = (count + 7) / 8;
	switch ( count  %  8)
	{
		case 0: do { *to++ = *from++;
		case 7: *to++ = *from++;
		case 6: *to++ = *from++;
		case 5: *to++ = *from++;
		case 4: *to++ = *from++;
		case 3: *to++ = *from++;
		case 2: *to++ = *from++;
		case 1: *to++ = *from++;
		} while ( --n > 0 );
	}
}

I have found this question over internet, calling send(p1,p2,15) will copy 15 ints from p2 to p1, but the first time case 7: triggers, how does this code repeats? case 0: do { ... is never called in this case and even then the loop runs back? the loop is even in-complete. what C++ feature am i missing which explains this?

Share this post


Link to post
Share on other sites
arbitus    440
It is essentially a memcopy performed in chunks of 8 int sized pieces of data. It works because of the fallthrough capability of the switch statement. As to why someone would use it? Learning exercise about loop unrolling, but that is about it.

Share this post


Link to post
Share on other sites
Mantear    251
On some platforms, particularily very old platforms, and under the right conditions, it can be an efficient implementation. However, memcpy will be just as fast, if not faster, than anything you can create on your own 99% of the time. Don't try something like this unless: A) you know memcpy isn't working for you, and B) you've profiled it and proved it's better.

Share this post


Link to post
Share on other sites
waZim    100
Quote:
Original post by Antheus
Duff's device.


Thanks alot, that was helpfull, Although my point was not what its doing or how it works. I was more concerned about how the first time the loop is entered.

calling send(p1,p2,15); will call it like this initially.

void send (int *to, int * from, int count)
{
int n = 1;
switch (7)
{
// Not this part missed //case 0: do { *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
} while ( --n > 0 );
}
}



I was not able to understand how even this loop works since in this case its in-complete. Or lets say "do" is not executed so how does the compiler knows its a loop? only from "while"?

Share this post


Link to post
Share on other sites
daviangel    604
In response to why anyone would write code like this if you use the Intel compiler you might need to be able to recognize unroll loops since it'll automatically insert some for you.
The Intel® Compilers can automatically unroll loops and insert branch-removing instructions.

Share this post


Link to post
Share on other sites
Zahlman    1682
Remember, C++ is a compiled language, not interpreted. 'do' is not some kind of command that gets executed when an interpreter gets to that point; it tells the compiler to create code for the loop, and that loop is always created. Similarly, the case labels mark points where the control flow can jump when the 'switch' is evaluated. When the code runs, the switch causes the processor to jump into the middle of the loop; when it gets to the end, it checks the loop condition and jumps back to the beginning, because that's how the loop was written ahead of time by the compiler - i.e. that's what the code written at the end of the loop says to do.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this