GG.*_*GG. 1 c c++ performance refactoring
只需在代码中略微修改即可计算两个数组的总和
int main()
{
int a[10000]={0}; //initialize something
int b[10000]={0}; //initialize something
int sumA=0, sumB=0;
for(int i=0; i<10000; i++)
{
sumA += a[i];
sumB += b[i];
}
printf("%d %d",sumA,sumB);
}
Run Code Online (Sandbox Code Playgroud)
要么
int main()
{
int a[10000]={0}; //initialize something
int b[10000]={0}; //initialize something
int sumA=0, sumB=0;
for(int i=0; i<10000; i++)
{
sumA += a[i];
}
for(int i=0; i<10000; i++)
{
sumB += b[i];
}
printf("%d %d",sumA,sumB);
}
Run Code Online (Sandbox Code Playgroud)
哪个代码会更快.
Rik*_*ood 25
只有一种方法可以知道,那就是测试和测量.您需要找出瓶颈所在的位置(CPU,内存带宽等).
数组中的数据大小(示例中为int)会影响结果,因为这会对处理器缓存的使用产生影响.通常,您会发现示例2更快,这基本上意味着您的内存带宽是限制因素(示例2将以更有效的方式访问内存).
这是使用VS2005构建的一些定时代码:
#include <windows.h>
#include <iostream>
using namespace std;
int main ()
{
LARGE_INTEGER
start,
middle,
end;
const int
count = 1000000;
int
*a = new int [count],
*b = new int [count],
*c = new int [count],
*d = new int [count],
suma = 0,
sumb = 0,
sumc = 0,
sumd = 0;
QueryPerformanceCounter (&start);
for (int i = 0 ; i < count ; ++i)
{
suma += a [i];
sumb += b [i];
}
QueryPerformanceCounter (&middle);
for (int i = 0 ; i < count ; ++i)
{
sumc += c [i];
}
for (int i = 0 ; i < count ; ++i)
{
sumd += d [i];
}
QueryPerformanceCounter (&end);
cout << "Time taken = " << (middle.QuadPart - start.QuadPart) << endl;
cout << "Time taken = " << (end.QuadPart - middle.QuadPart) << endl;
cout << "Done." << endl << suma << sumb << sumc << sumd;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行此版本,后一版本通常更快.
我尝试编写一些汇编程序来击败第二个循环,但我的尝试通常较慢.所以我决定看看编译器生成了什么.这是为第二个版本中的主要求和循环生成的优化汇编程序:
00401110 mov edx,dword ptr [eax-0Ch]
00401113 add edx,dword ptr [eax-8]
00401116 add eax,14h
00401119 add edx,dword ptr [eax-18h]
0040111C add edx,dword ptr [eax-10h]
0040111F add edx,dword ptr [eax-14h]
00401122 add ebx,edx
00401124 sub ecx,1
00401127 jne main+110h (401110h)
Run Code Online (Sandbox Code Playgroud)
这是注册用法:
这里有一些有趣的事情:
要真正理解为什么这么快,你需要使用英特尔的VTune性能分析器来查看CPU和内存停滞的位置,因为这段代码非常违反直觉.
理论上,由于缓存优化,第二个应该更快.
缓存经过优化,可以传输和保留数据块,因此对于第一次访问,您将获得第一个数据块的大部分进入缓存.在第一个代码中,可能会发生当您访问第二个阵列时,您可能需要取出第一个阵列的一些数据,因此需要更多访问.
在实践中,这两种方法将花费或多或少的同时,考虑到实际缓存的大小,并且根本没有数据被从缓存中取出,这是第一种方法.
注意:这听起来很像家庭作业.在这些尺寸的现实生活中,第一个选项会稍快一些,但这只适用于这个具体的例子,嵌套循环,更大的阵列或特别小的缓存大小会对性能产生重大影响,具体取决于顺序.
| 归档时间: |
|
| 查看次数: |
609 次 |
| 最近记录: |