This is sort of a silly question, but it's been bothering me and I couldn't google-fu my way over it.
Consider the following array:
struct SomeDataStruct
{
uint64_t ValueOne;
uint64_t ValueTwo;
uint64_t ValueThree;
};
SomeDataStruct _veryLargeArray[1024];
Now, which of these approaches are faster to loop over every element and do something with each one?
Approach 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;
}
Approach 2:
SomeDataStruct * pEndOfStruct = &(_veryLargeArray[1024]);
for (SomeDataStruct * ptr = _veryLargeArray; ptr != pEndOfStruct; ptr += 1)
{
ptr->ValueOne += 1;
ptr->ValueTwo += 1;
ptr->ValueThree = ptr->ValueOne + ptr->ValueTwo;
}
I know the question seems really stupid on its surface, but what I'm wondering is does the compiler do anything smart/special with each given way of implementing the for loop? In the first case, it could be really memory intensive if the compiler actually looked up BaseArrayPointer + Offset every time, but if the compiler is smart enough if will fill the L2 cache with the entire array and treat the code between the { }'s correctly.
The second way gets around if the compiler is resolving the pointer every time, but probably makes it real hard for a compiler to figure out that if could copy the entire array into the L2 cache and walk it there.
Sorry for such a silly question, I'm having a lot of fun learning c++ and have started doing that thing where you overthink everything. Just curious if anyone knew if there was a "definitive" answer.