473,395 Members | 2,796 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Duff's Device

I've been wondering sometimes:
Anyone know why Duff's device is usually written like this:

Expand|Select|Wrap|Line Numbers
  1. void duff(const char *str, int len) {
  2. int n = (len + 7) / 8;
  3. switch (len % 8) {
  4. case 0: do{ foo(*str++);
  5. case 7:     foo(*str++);
  6. case 6:     foo(*str++);
  7. ...
  8. case 1:     foo(*str++);
  9. } while (--n 0);
  10. }
  11. }
instead of this?

Expand|Select|Wrap|Line Numbers
  1. void duff2(const char *str, int len) {
  2. switch (len % 8) {
  3. case 0: while ((len -= 8) >= 0) {
  4. foo(*str++);
  5. case 7: foo(*str++);
  6. case 6: foo(*str++);
  7. ...
  8. case 1: foo(*str++);
  9. }
  10. }
  11. }
The original has an extra '+' and doesn't handle len=0.
Nor does it need the divide by 8, though I realize n-=1
may be cheaper than n-=8 on some architectures.
People have had 18 years to notice now:-)

--
Hallvard
Sep 28 '06 #1
11 2435
I wrote:
I've been wondering sometimes:
Anyone know why Duff's device is usually written like this:
(...)
Er, a bit silly question - "that's the way it's published" of course.
I meant, is there a good reason to write it that way - produces
better code on some machine?

--
Hallvard
Sep 28 '06 #2
Hallvard B Furuseth wrote:
I've been wondering sometimes:
Anyone know why Duff's device is usually written like this:

void duff(const char *str, int len) {
int n = (len + 7) / 8;
switch (len % 8) {
case 0: do{ foo(*str++);
case 7: foo(*str++);
case 6: foo(*str++);
...
case 1: foo(*str++);
} while (--n 0);
}
}

instead of this?

void duff2(const char *str, int len) {
switch (len % 8) {
case 0: while ((len -= 8) >= 0) {
foo(*str++);
case 7: foo(*str++);
case 6: foo(*str++);
...
case 1: foo(*str++);
}
}
}

The original has an extra '+' and doesn't handle len=0.
Nor does it need the divide by 8, though I realize n-=1
may be cheaper than n-=8 on some architectures.
People have had 18 years to notice now:-)
I did some speed test some time ago with gcc on x86 and the fastest
version I was able to find was:

static inline void
ooc_memchr_copy( char *restrict dst,
const char *restrict src, size_t cnt)
{
size_t rem = cnt % 8;
cnt = (cnt / 8) + 1;

switch (rem)
do { *dst++ = *src++;
case 7: *dst++ = *src++;
case 6: *dst++ = *src++;
case 5: *dst++ = *src++;
case 4: *dst++ = *src++;
case 3: *dst++ = *src++;
case 2: *dst++ = *src++;
case 1: *dst++ = *src++;
case 0: ;
} while(--cnt);
}

which is not the one published and works for cnt==0 as well as for
cnt==(size_t)-1. Why do you think that the orignal version is always the
one used?

a+, ld.
Sep 28 '06 #3

"Hallvard B Furuseth" <h.**********@usit.uio.nowrote in message
news:hb**************@bombur.uio.no...
Anyone know why Duff's device is usually written
like this (snip) instead of this? (snip)
Yes.

This is his original post:
http://groups.google.com/group/net.l...e07aa94c?hl=en

This is another post from him with clarifications to various questions from
individuals on c.l.c:
http://groups.google.com/group/comp....75c42411?hl=en

From the original post, he (indirectly) states that the design of Duff's
Device in C was the direct result of his understanding of how to generate
efficient unrolled loops in assembly language for the VAX. At least, that
is the one thing other than Duff's Device that you should get from his
message...
FYI, others have pointed out Simon Tatham's "Coroutines in C":
http://www.chiark.greenend.org.uk/~s...oroutines.html

Protothreads is also based on a similar mechanism:
http://www.sics.se/~adam/pt/
Rod Pemberton
Sep 28 '06 #4
"Rod Pemberton" <do*********@bitfoad.cmmwrites:
"Hallvard B Furuseth" <h.**********@usit.uio.nowrote in message
news:hb**************@bombur.uio.no...
>Anyone know why Duff's device is usually written
like this (snip) instead of this? (snip)

Yes.

This is his original post:
http://groups.google.com/group/net.l...e07aa94c?hl=en

This is another post from him with clarifications to various questions from
individuals on c.l.c:
http://groups.google.com/group/comp....75c42411?hl=en
[...]

And here's the scary part:

| It amazes me that after 10 years of writing C there are still little
| corners that I haven't explored fully. (Actually, I have another
| revolting way to use switches to implement interrupt driven state
| machines but it's too horrid to go into.)

Does anyone know the details? If the orginal Duff's Device wasn't
"too horrid to go into" ... (*shudder*).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Sep 28 '06 #5
Keith Thompson <ks***@mib.orgwrote:
Does anyone know the details? If the orginal Duff's Device wasn't
"too horrid to go into" ... (*shudder*).
One might even call it "Duff's Last Theorem" :-)

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Sep 29 '06 #6
Keith Thompson wrote:
And here's the scary part:

| It amazes me that after 10 years of writing C there are still little
| corners that I haven't explored fully. (Actually, I have another
| revolting way to use switches to implement interrupt driven state
| machines but it's too horrid to go into.)

Does anyone know the details? If the orginal Duff's Device wasn't
"too horrid to go into" ... (*shudder*).
http://www.chiark.greenend.org.uk/~s...oroutines.html

Sep 29 '06 #7
"Harald van D?k" <tr*****@gmail.comwrote in message
news:11**********************@c28g2000cwb.googlegr oups.com...
Keith Thompson wrote:
And here's the scary part:

| It amazes me that after 10 years of writing C there are still little
| corners that I haven't explored fully. (Actually, I have another
| revolting way to use switches to implement interrupt driven state
| machines but it's too horrid to go into.)

Does anyone know the details? If the orginal Duff's Device wasn't
"too horrid to go into" ... (*shudder*).

http://www.chiark.greenend.org.uk/~s...oroutines.html
The best part is it ends with "Share and Enjoy"*!

*"Share and Enjoy" is, of course, the company motto of the hugely successful
Sirius Cybernetics Corporation Complaints division, which now covers the
major land masses of three medium sized planets and is the only part of the
Corporation to have shown a consistent profit in recent years.
Oct 2 '06 #8
Laurent Deniau writes:
Hallvard B Furuseth wrote:
>I've been wondering sometimes:
Anyone know why Duff's device is usually written like this:
(...)
I did some speed test some time ago with gcc on x86 and the fastest
version I was able to find was:

static inline void
ooc_memchr_copy( char *restrict dst,
const char *restrict src, size_t cnt)
{
size_t rem = cnt % 8;
cnt = (cnt / 8) + 1;
(...)
Heh. Strange, keeps an add but still speeds it up.
which is not the one published and works for cnt==0 as well as for
cnt==(size_t)-1. Why do you think that the orignal version is always
the one used?
It isn't; it's just the one I've _usually_ seen. (Not that I've seen
the device used all that often:-)
--
Hallvard
Oct 3 '06 #9
Rod Pemberton writes:
FYI, others have pointed out Simon Tatham's "Coroutines in C":
http://www.chiark.greenend.org.uk/~s...oroutines.html
Cool. Why didn't anyone tell me about that __LINE__ trick before?:-)
I wouldn't call them coroutines though. Too limited.

Personally I don't see anything ugly about it, BTW. Hiding ugly stuff
is one of the things macros are _for_. Except the crFinish macro, but
that one is not necessary:

#define AutoSwitch(state) /* state=integer state variable */\
switch (state) case 0:
#define AScontrol(state, stmt) /* stmt=return/break/continue/goto */\
if (1) { (state) = __LINE__; stmt; case __LINE__:; } else (void)(0)

Now it's just a normal switch in that break/continue/etc work as
normally - it's just that the case statements look nicer this way.

int foo(void)
{
static int state, cur;
AutoSwitch(state)
for (cur = 1; cur < 10; cur++)
AScontrol(state, return cur*cur);
return 0;
}
--
Hallvard
Oct 3 '06 #10
Hallvard B Furuseth wrote:
Personally I don't see anything ugly about it, BTW. Hiding ugly stuff
Go look at the Putty code and report back to us.
Oct 3 '06 #11
Christopher Layne writes:
>Hallvard B Furuseth wrote:
>Personally I don't see anything ugly about it, BTW. Hiding ugly stuff

Go look at the Putty code and report back to us.
OK, now that has way too many magic macros to keep track of.
(Which is one reason I made 'return' etc arguments to my variants BTW,
that way if there is a return statement somewhere it is in the body.)

--
Hallvard
Oct 3 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Jamie Risk | last post by:
In Tom's original post (see http://www.lysator.liu.se/c/duffs-device.html) discussing "Duff's Device" he refers to "another revolting way to use swtiches to implement interrupt driven state...
2
by: Christopher Benson-Manica | last post by:
(Fear not, I have no intention of actually using it!) Was there a particular reason Duff chose to unroll the loop 8 times, as opposed to some other number of times (besides some reason having to...
22
by: Jan Richter | last post by:
Hi there, the Code below shows DJBs own implementation of strlen (str_len): unsigned int str_len(char *s) { register char *t; t = s; for (;;) { if (!*t) return t - s; ++t;
8
by: Tony Liu | last post by:
I am having a "Null Device is Missing" compile error when compiling a c++ project. The documentation from MSDN said it could be caused by low system resource or the user account does not have...
2
by: Rosalind Chen | last post by:
Hi, This is the first time that I use Visual Studio .NET. And I stucked in this first problem. - I created a SDK from Platform builder 4.2 that includes .Net Compact Framework. - installed...
0
by: Shival | last post by:
Hi, I have a Device that will be used by dentist to take their paitient teaath pics. this Device is having a click button from which the device takes pics. The Device is configured to my OS...
10
by: anon.asdf | last post by:
Here's a reminder of duff's device: /*************************************/ #include <stdio.h> #define STEP 8 #define MAX_LEN STEP*4+1 #define SOURCE_LEN 28
9
by: yawnmoth | last post by:
dsend(to, from, count) char *to, *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:...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.