【问题标题】:Within c++ function, pointer vs indexed array在c ++函数中,指针与索引数组
【发布时间】:2012-07-11 17:30:29
【问题描述】:

这个问题类似于earlier 提出的问题,但我认为不考虑内存分页。所以,我在这里再次提出类似的问题:

// version 1
int nums[100];
int* pNum = nums;
for(int i=0;i<100;i++,pNum++){
  foo(pNum);
}

// version 2
for(int i=0;i<100;i++){
  foo(nums[i]);
}

哪个版本会更快?之前有人说生成的汇编代码会非常相似,因为两个版本都需要递增内存地址的位置,但是考虑到一个非常大的数组,内存分页性能会显着改变吗?因为其中一个需要长移位,而另一个需要从数组的基内存地址移位?我知道它非常依赖于平台/编译器,但仍想了解人们的常见做法,尤其是处理大型数据类型,如图像处理或科学计算?谢谢。

【问题讨论】:

  • 尝试两者的时间并自己看看。但我警告说,现代编译器非常有能力将一种形式转换为另一种形式。所以可能很难进行基准测试。
  • 你不应该担心这样的小细节。编译器足够聪明,无论您如何编写它都可以优化它。此外,像这样的微优化几乎都是浪费时间。效率低下的原因通常要大得多。
  • 实际上,这是一个面试问题,我已经说过类似@templatetypedef 的内容,但我认为这对芯片组制造商来说真的很重要。
  • @Mysticial,如果我在关闭编译器优化的情况下尝试两个版本是否有意义?
  • TBH,我之前实际上已经玩过这个特定的优化。而且没有明确的赢家。它们不一样,但都不是总是更快。当您增加多个指针时,它会变得很有趣。第一个版本有更多的增量,但第二个版本有间接寻址和更多的寄存器压力。我已经看到高达 50% 的差异。但如前所述,它非常依赖于硬件和编译器的环境。我认为它是一种难以解决的微优化。

标签: c++ optimization pointers compiler-construction paging


【解决方案1】:

我知道它非常依赖于平台/编译器

没错

但仍想了解人们的常见做法,尤其是处理图像处理或科学计算等大型数据类型?谢谢。

这两种做法都很常见,就像使用向量和迭代器一样。您正在担心一些极有可能无关紧要的事情。使用最能表达您在脑海中可视化算法的方式的任何内容,这样更容易正确维护和发展。

【讨论】:

    【解决方案2】:

    普遍的共识是,对于原始类型,没有区别。大多数编译器会为此生成完全相同的代码(大概您的意思是foo(*pNum))。

    【讨论】:

    • 如果它不生成相同的代码,我想它更有可能在版本 1 上“搞砸”,因为它不是编写代码的典型方式,并且使用指针,编译器偶尔会遇到麻烦。
    • 你考虑缓存未命中/内存分页吗?假设 pNum 当前指向地址 base_address+10*sizeof(int),在这种情况下,CPU 可能会认为从 base_address+10*sizeof(int) 缓存到 30*sizeof(int) 是个好主意。但是对于有索引的数组,没有提示处理数组的哪一部分?
    • 大多数编译器都有输出 asm 代码的选项(例如 gcc 上的 -S)。带有 -O1 的 gcc 完全为这两种情况生成相同的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 2012-08-02
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多