这是一个有效的C代码吗?

jos*_*osh 3 c c++ cpu-registers

可能重复:
代码有什么作用?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

以上是有效的C代码吗?如果是这样,它想要实现什么,为什么有人会像上面这样做?

Ben*_*igt 9

它被称为Duff的设备,您可以在维基百科上阅读它.

它解决了展开循环的一个问题:可能需要非整数次传递.一种方法是在主循环之外处理这个问题,但是使用Duff的设备更有效,它使用非常快速的跳转表并避免额外的循环开销来处理奇数个操作.

在您的示例中,这是一个内存副本,请与天真的版本进行比较:

void memcpy(char* dst, char* src, size_t count)
{
   begin:
     if (count-- == 0) return;
     *(dst++) = *(src++);
     goto begin;
}
Run Code Online (Sandbox Code Playgroud)

要复制15个字节,请执行以下操作:

测试计数,复制,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,复制,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,副本,循环,测试计数,复制,循环,测试计数

注意必须完成"测试计数"和"循环"操作的次数.

使用你展示的duff版本,它更简单:

基于计数,复制,复制,复制,复制,复制,副本,副本,测试计数,循环,副本,副本,副本,副本,副本,副本,副本,副本,测试计数跳

这节省了一半以上的步骤


fas*_*all 5

这是有效的.这是一个非常老派的循环展开.

基本上,不是检查被复制的每个字符的计数以确定何时停止,而只需要检查ceil(n/8)次.

register关键字只是一个编译器提示,表明编译器试图将该值保存在寄存器中,而不是将其随机存入和移出主存储器.

显然,这样的东西不再是必要的(memcpy()很可能在你编写的任何机器上实现非常快速的实现)但这样的技巧实际上提供了相当不错的性能获胜.