C - 复制数据结构的速度与部件完全相同

时间:2014-09-01 18:42:41

标签: c optimization data-structures

我正在使用C"中的数据结构和程序设计。 Kruse,Leung和Tondo。第2章第2节介绍了一个简单的数据结构(列表),后来要求读者为结构编写两个不同的复制函数。有关的练习是E2,内容如下:

  

编写将一个列表复制到另一个列表的函数(作为文本中定义的结构类型)。使用以下方法:(a)复制整个结构; (b)使用循环仅复制条目。哪个版本更容易编写?哪个版本通常运行得更快,为什么?

我的问题在于本练习的最后一部分:"哪个版本通常运行得更快,为什么?"。我知道复制整个结构更快,我的理解表明这是因为可以避免循环的开销。然而,当我每次运行时,我惊讶地发现复制整个结构不仅比复制每个条目更快,而且大约快10倍

我希望有人能够向我解释为什么会这样,或者至少指引我找一个有助于我理解的来源。我试着阅读我编写的两个函数的汇编,但是我对汇编的理解是非常基本的。

谢谢!

相关代码:

#define MAXLIST 200 //maximum size of lists

extern void Error(const char *);

typedef struct coord_tag {
    int row;    //x
    int col;    //y
} Coord_type;

typedef Coord_type Entry_type;

typedef struct list_tag {
    int count;
    Entry_type entry[MAXLIST];
} List_type;

void Copy(List_type *lt, List_type *lf) //list "to" and list "from"
{
    if (lt == NULL || lf == NULL) {
        Error("list uninitialized");
    } else {
        *lt = *lf;
    }
}

void Copy2(List_type *lt, List_type *lf)
{
    if (lt == NULL || lf == NULL) {
        Error("list uninitialized");
    } else {
        int i;

        lt->count = lf->count;
        for (i = 0; i < lf->count; i++) {
            lt->entry[i] = lf->entry[i];
        }
    }
}

1 个答案:

答案 0 :(得分:1)

直接记忆副本的速度有多快你会感到惊讶!在汇编中,有专门用于快速存储器复制的指令。 (例如REP MOVSB)让我们看一下第二个副本在每个循环迭代中引入的所有新中断:

  • i ++在
    • 缓存i
    • 的原始值
    • 在内存中增加i
    • 最后返回i
    • 的原始值
  • LF-&GT;条目[I]
    • 检索lf
    • 的值
    • 检索i的值
    • 将i加上条目的偏移量添加到lf
    • 检索该地址的值
  • LT-&GT;条目[I]
    • 检索lt
    • 的值
    • 检索i的值
    • 将i加上条目的偏移量添加到lt
  • i&lt; LF-&GT;计数
    • 检索lf
    • 的值
    • 检索lf-&gt; count
    • 的值
    • 检索i的值
    • 将i与lf-&gt; count
    • 进行比较

你可以想象为什么这会比不间断的内存拷贝慢10倍。