разница во времени процессора для двух похожих строк

В моей программе есть цикл 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) Почему между этими двумя строками огромная разница во времени процессора?

Спасибо!

5
задан Brian Webster 18 July 2011 в 15:13
поделиться