В моей программе есть цикл while, где IterZNext
, IterZ
- указатели на узлы в списке. Узлы в списке относятся к типу struct с полем, называемым «Индекс».
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;
}
}
Когда я профилировал свою программу, я обнаружил, что строка (*)
NextIndex1 = IterZNext->Index;
потребляет большую часть времени процессора (2,193 с), а строка ( **)
NextIndex = IterZNext->Index;
, что почти совпадает со строкой (*), использует только 0,093 с. Я использовал усилитель Intel VTune, чтобы увидеть сборку этих двух строк, которая выглядит следующим образом:
Address Line Assembly CPU Time Instructions Retired
Line (*):
0x1666 561 mov eax, dword ptr [ebp-0x44] 0.015s 50,000,000
0x1669 561 mov ecx, dword ptr [eax+0x8]
0x166c 561 mov dword ptr [ebp-0x68], ecx 2.178s 1,614,000,000
Line (**):
0x166f 562 mov byte ptr [ebp-0x155], 0x1 0.039s 80,000,000
0x1676 562 mov eax, dword ptr [ebp-0x44] 0.027s 44,000,000
0x1679 562 mov ecx, dword ptr [eax+0x8]
0x167c 562 mov dword ptr [ebp-0x5c], ecx 0.026s 94,000,000
Если я изменю порядок строки () и строки ( *), программа изменится на
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;
NextIndex = IterZNext->Index; // line (**)
NextIndex1 = IterZNext->Index; // line (*)
IterZNext->Index;
}
}
, а результат для сборки меняется на
Address Line Assembly CPU Time Instructions Retired
Line (**):
0x1666 560 mov byte ptr [ebp-0x155], 0x1 0.044s 84,000,000
0x166d 560 mov eax, dword ptr [ebp-0x44] 0.006s 2,000,000
0x1670 560 mov ecx, dword ptr [eax+0x8] 0.001s 4,000,000
0x1673 560 mov dword ptr [ebp-0x5c], ecx 1.193s 1,536,000,000
Line (*):
0x1676 561 mov eax, dword ptr [ebp-0x44] 0.052s 128,000,000
0x1679 561 mov ecx, dword ptr [eax+0x8]
0x167c 561 mov dword ptr [ebp-0x68], ecx 0.034s 112,000,000
. В этом случае строка (* ) использует большую часть времени процессора (1,245 секунды), а строка () использует только 0,086 секунды.
Может кто-нибудь скажите мне: (1) Почему выполнение первого задания занимает так много времени? Обратите внимание, что в строке zz = xx + yy используется только 0,058 с. Связано ли это с промахами кеша? поскольку все узлы в списке генерируются динамически. (2) Почему между этими двумя строками огромная разница во времени процессора?
Спасибо!