繁体   English   中英

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

[英]What is the most efficient way to loop over an array? (c++)

这是一个愚蠢的问题,但这一直困扰着我,我无法以谷歌的方式解决它。

考虑以下数组:

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

SomeDataStruct _veryLargeArray[1024];

现在,以下哪种方法可以更快地遍历每个元素并对每个元素执行某项操作?

方法1:

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版本的编译结果要比手工编码的程序集慢。

另一方面,可能需要花一点时间了解缓存以及引擎盖下发生的事情。 但是通常,这是在您发现代码不够快之后发生的。 否则,就有过早优化的风险,这是万恶之源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM