C++ 优化成员阵列访问(mov指令)

C++ 优化成员阵列访问(mov指令),c++,optimization,gcc,assembly,C++,Optimization,Gcc,Assembly,以下是性能分析器报告的一部分: for (node* p = array[index]; p != NULL; p = p->next ) 52,55 : cb40a: mov (%edi,%edx,4),%ebp 正如您所看到的,在该函数中花费的一半时间用于表示“p=array[index]”访问的特定指令(%edi是“this”指针,%edx是计算索引) 为什么要花这么长时间?循环中有调用和比较,但大部分时间都花在这个执行一次的简单mov上

以下是性能分析器报告的一部分:

for (node* p = array[index]; p != NULL; p = p->next )
   52,55 :           cb40a:       mov    (%edi,%edx,4),%ebp
正如您所看到的,在该函数中花费的一半时间用于表示“p=array[index]”访问的特定指令(%edi是“this”指针,%edx是计算索引)

  • 为什么要花这么长时间?循环中有调用和比较,但大部分时间都花在这个执行一次的简单mov上。我想通常这个列表只包含很少的元素,所以循环体不会花费太多时间,但仍然
  • 如何优化它
  • 数组访问只发生一次,函数从中获取起始元素。通常,该函数会将节点数据与键进行比较,如果比较失败,则返回“p”或NULL。也就是说,大多数时间p->next为空

    即使我们假设内存访问只发生两次:在array[index]和在p->next中,那么为什么第一次比第二次慢那么多(大约是函数的5%)

    如果这是缓存问题,我想知道为什么会发生,以及如何找到可能的解决方案(即重新安排内存访问等)

    完整功能(类型):


    这里的key()和compare()是简单的内联函数。

    是否可以先尝试预取数组?(类似于,
    \u内置预取(数组,0,3);
    在函数中使用它之前的某个地方?嗯,如果函数只需要访问数组一次,并且只需要从数组中访问单个元素(开始节点),这会有帮助吗)?您是否确定
    mov
    是通过索引到
    数组
    生成的。如果gcc没有将
    p
    初始化到适当的元素,我会感到惊讶。
    mov
    语句可能来自
    p=p->next
    。我觉得这不大可能,您能发布一个可编译的示例来说明您真正在做什么吗ng?也许大多数数组项已经是
    nullptr
    ,即空列表?否,p->next通过lea 0xc(%ebp),%eax完成。
    node* list::find(int key)
    {
      if (!this->array) return 0;
      node* dummy = 0;
      int index = calcindex(key);
      for (node* p = this->array[index]; p != NULL; p = p->next)
      {
        if (p->key() == key && check(p->data, key))
          return p;
        dummy = p; // forgot to remove this stuff, probably optimized away
      }
      return 0;
    }