Hi all. There is a while loop in my program, where IterZNext, IterZ are pointers to nodes in a list. The nodes in the list are of type struct with a field called "Index".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
double xx = 20.0;
double yy = 10000.0;
double zz;
while (IterZNext!=NULL && NextIndex<=NewIndex)
{
IterZ=IterZNext;
IterZNext = IterZ->Next;
if (IterZNext!=NULL)
{
zz = xx + yy;
NextIndex1 = IterZNext->Index; // line (*)
NextIndex = IterZNext->Index; // line (**)
IterZNext->Index;
}
}
When I profiled my program, I found the line (*)
NextIndex1 = IterZNext->Index;
consumes most of CPU time (2.193s), while the line (**)
NextIndex = IterZNext->Index;
which is all most the same with the line (*) only uses 0.093s. I used the Intel VTune Amplifier to see the assembly of these two lines, which is as follows:
In this case, line (**) uses most of CPU time (1.245s) while line (*) only uses 0.086s.
Could someone tell me:
(1) Why does it take so long to make the first assignment? Notice that the line zz=xx+yy only uses 0.058s. Is this related to the cache misses? since all nodes in the list are dynamically genereated.
(2) Why is there huge difference in CPU time between this two lines?
Interesting. This is a topic I know NOTHING about, hehe. But even with my ignorance, I'll guess: Your compiler detects that the second assignment uses the same value as the first one, and then the code for the second assignment doesn't need to move the right-hand side into the register again and it just uses the value used before.
thanks for your reply webJose! but it is unusual that it takes so long to make the first assignment. (Notice that the line zz=xx+yy only uses 0.058s.) Maybe related to the cache misses? since all nodes in the list are dynamically genereated.
Well, why it takes so long to run the first assignment is an entirely different question than "why there is such difference in CPU between assignment 1 and 2?". I guessed an answer for your original question; for this new question of yours, I have no answer or guess. :-(
1) The stack frame will always be in the cache because you're accessing it all the time. So any reads or writes around ebp will be fast.
2) The instruction at 0x1669 is the dereference of IterZNext (eax is the value of IterZNext and Index is 8 bytes into the struct)
3) This dereference is likely to cause a cache miss as we have had no reason to go anywhere near this bit of memory before.
4) The instruction at 0x1679 does the dereference again, but this time the memory is in the cache. As we haven't accessed anything to cause the cache to drop it (remember the stack frame is always in cache)
I think the rather more interesting thing is the instruction at 0x166f. Which local variable is at ebp-0x155 and why are we setting it to 0x1?
Thanks, kev82. I think you are probably right. Just one more question: if the instruction at 0x1669 is the dereference of IterZNext which causes the cache miss, why does the instruction at 0x166c rather than the instruction at 0x1669 consume most of CPU time? Is this a bug of Intel VTune Amplifier?