utr*_*rbc 5 c c++ assembly profiling cpu-usage
有一个在我的节目,其中一个while循环IterZNext,IterZ是指向列表中的节点.列表中的节点是struct类型,带有一个名为"Index"的字段.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我描述我的程序时,我找到了行(*)
NextIndex1 = IterZNext->Index;
Run Code Online (Sandbox Code Playgroud)
消耗大部分CPU时间(2.193s),而行(**)
NextIndex = IterZNext->Index;
Run Code Online (Sandbox Code Playgroud)
与行(*)最相似的只使用0.093s.我使用英特尔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
Run Code Online (Sandbox Code Playgroud)
如果我改变了line()和line(*)的顺序,那么程序将改为
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;
}
}
Run Code Online (Sandbox Code Playgroud)
并且程序集的结果更改为
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,line(*)使用大部分CPU时间(1.245s),而line()仅使用0.086s.
有人能告诉我:(1)为什么要做第一次任务需要这么长时间?请注意,行zz = xx + yy仅使用0.058s.这与缓存未命中有关吗?因为列表中的所有节点都是动态生成的.(2)为什么这两行之间的CPU时间差异很大?
谢谢!
所有现代CPU都是超级分类器和无序的 - 这意味着指令实际上并没有按照程序集的顺序执行,并且实际上并没有当前的PC - 飞行和执行中有很多10条指令立刻.
因此,CPU报告的任何采样信息只是CPU执行的一个粗略区域 - 它正在执行采样中断关闭时指示的指令; 但它也在执行所有其他飞行中的!
然而人们已经习惯了(和期望)分析工具来告诉他们究竟哪个单独的指令的CPU当前正在运行-所以当采样中断触发CPU基本上是挑选的许多积极的指令之一是"当前"之一.
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |