这是有效的 C 代码吗?
可能的重复:
这段代码的作用是什么?
void duff(register char *to, register char *from, register int count)
{
register 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);
}
}
上面的 C 代码是有效的吗?如果是这样,它想要实现什么目的以及为什么有人会做上述事情?
Possible Duplicate:
What does the code do?
void duff(register char *to, register char *from, register int count)
{
register 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);
}
}
Is the above valid C code? If so, what is it trying to achieve and why would anyone do something like the above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它被称为达夫的设备,您可以在维基百科。
它解决了展开循环的一个问题:可能需要非整数的传递次数。一种方法是在主循环之外处理这个问题,但使用 Duff 的设备更有效,该设备使用非常快的跳转表,并避免处理奇数操作的额外循环开销。
在您的示例中,这是一个内存副本,请与原始版本进行比较:
要复制 15 个字节,将执行以下操作:
请注意必须执行“测试计数”和“循环”操作的次数。
使用您展示的达夫版本,它要简单得多:
可节省一半以上的步骤
It's called Duff's device and you can read about it on wikipedia.
It takes care of one problem with an unrolled loop: there could be a non-integer number of passes needed. One method is to deal with this outside the main loop, but it's more efficient to use Duff's device which uses a very fast jump table and avoids extra looping overhead dealing with the odd number of operations.
In your example, which is a memory copy, please compare to the naive version:
To copy 15 bytes, this does the following:
Note how many times the "test count" and "loop" operations must be done.
Using duff's version which you showed, it is much simpler:
which saves over half the steps
这是有效的。这是一个非常老式的循环展开。
基本上,它不必检查正在复制的每个字符的计数来确定何时停止,而只需检查 ceil(n/8) 次。
register 关键字只是一个编译器提示,建议编译器尝试将该值保留在寄存器中,而不是将其混入或混出主内存。
显然,这样的东西不再是真正必要的了(memcpy() 可能在您正在编码的任何机器上都有一个非常快的实现),但是这样的技巧实际上可以提供相当不错的性能胜利。
It's valid. It's a very old-school loop unroll.
Basically, instead of checking the count for every character that's being copied to determine when to stop, it only has to check ceil(n/8) times.
The register keyword is just a compiler hint to suggest that the compiler try to keep that value in a register instead of shuffling it in and out of main memory.
Obviously stuff like this isn't really necessary anymore (memcpy() is likely to have a very fast implementation on whatever machine you're coding for) but tricks like this used to actually provide pretty decent performance wins.
指向 维基百科上的达夫设备的强制链接。
Obligatory link to Duff's Device on Wikipedia.