gpt4 book ai didi

c++ - 遍历数组最有效的方法是什么? (c++)

转载 作者:行者123 更新时间:2023-11-28 04:13:20 29 4
gpt4 key购买 nike

这是一个有点愚蠢的问题,但它一直困扰着我,我无法通过 google-fu 解决它。

考虑以下数组:

struct SomeDataStruct
{
uint64_t ValueOne;
uint64_t ValueTwo;
uint64_t ValueThree;
};

SomeDataStruct _veryLargeArray[1024];

现在,在遍历每个元素并对每个元素执行某些操作时,这些方法中的哪一个更快?

方法一:

for (int i = 0; i < 1024; ++i)
{
_veryLargeArray[i].ValueOne += 1;
_veryLargeArray[i].ValueTwo += 1;
_veryLargeArray[i].ValueThree = _veryLargeArray[i].ValueOne + _veryLargeArray[i].ValueTwo;
}

方法二:

SomeDataStruct * pEndOfStruct = &(_veryLargeArray[1024]);

for (SomeDataStruct * ptr = _veryLargeArray; ptr != pEndOfStruct; ptr += 1)
{
ptr->ValueOne += 1;
ptr->ValueTwo += 1;
ptr->ValueThree = ptr->ValueOne + ptr->ValueTwo;
}

我知道这个问题表面上看起来真的很愚蠢,但我想知道编译器是否对每种给定的 for 循环实现方式做了任何聪明/特殊的事情?在第一种情况下,如果编译器实际上每次都查找 BaseArrayPointer + Offset,那么它可能会占用大量内存,但是如果编译器足够聪明,它会用整个数组填充 L2 缓存并处理 {} 之间的代码正确。

如果编译器每次都解析指针,则第二种方法可以绕过,但可能会使编译器很难弄清楚是否可以将整个数组复制到 L2 缓存并将其遍历到那里。

很抱歉提出这样一个愚蠢的问题,我从学习 C++ 中获得了很多乐趣,并且已经开始做那些你想得太多的事情。只是好奇是否有人知道是否有“确定”的答案。

最佳答案

除非您想查看中间汇编语言输出并分析 CPU 的缓存行为,否则您能够回答此问题的唯一方法是分析代码。运行它,数百或数千次,看看需要多长时间。

如果您想要最快的代码,请编写最简单、最明显的版本并将其留给优化编译器。如果您尝试变得花哨,使用这样的循环,您可能会混淆编译器并且它无法优化事物。

我看到一个简单的 C 循环编译比手工编码的汇编更快,而手工优化的 C 版本最终比手工编码的汇编慢。

另一方面,了解一些关于缓存以及幕后发生的事情也是值得的。但通常,这种情况发生在您发现您的代码不够快之后。否则会冒过早优化的风险,即 root of all evil .

关于c++ - 遍历数组最有效的方法是什么? (c++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57212793/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com