我的变量声明如何影响执行时间

时间:2015-09-08 18:29:17

标签: c++ performance

我是电路设计师(不是软件向导),过去9个月一直在研究数值算法。作为评估算法有效性的一种方法,我会监控收敛解决方案所需的时间。

大约6个月前,我发现我声明变量的方式会对程序运行所需的时间产生巨大影响。例如,简单地重新排列声明(如下所示)可以使运行代码所需的时间加倍。简单地改变阵列的长度也会同样影响问题。

int N, j, Iter;
long double RealZero, RealErr, QuadIterErr, QuadX;
long double TUV[3], QuadQP[102], RealQP[102];
bool Updated;

int N, j, Iter;
long double RealZero, RealErr, QuadIterErr, QuadX;
long double QuadQP[102], RealQP[102];
bool Updated;
long double TUV[3];

我最初认为我有某种错误,但我找不到它。除了速度之外,我没有看到任何其他异常,无论代码运行缓慢还是快速,我都会得到相同的结果。

我找到了一些与包装长双打有关的问题的讨论,但我不明白其中任何一个,他们从未说过如何解决他们正在讨论的问题。

有人可以告诉我一些关于这里可能会发生什么以及如何解决的问题吗?

我需要的是一致性而不是我需要的速度。我没有使用任何速度优化器(默认编译器设置),我使用的是C ++ Builder XE3。我没有使用#pragma pack(正如有人问的那样)。

根据评论,我设置了慢速和快速执行的声明,并比较了所有长双变量的基址。无论是慢速还是快速,地址都以0,4,8或C结尾。

2 个答案:

答案 0 :(得分:1)

确实影响代码性能的一件事是未对齐的数据:x86平台可以读取未对齐的数据(与其他一些架构不同),但会受到性能损失。

什么是未对齐访问权限?当类型的大小未存储在该大小的倍数的地址时。因此,如果将32位整数存储在奇数地址,或者甚至存储在不是4的倍数的偶数地址,则CPU可能必须执行两次内存读取以获取两半数据。

在这种情况下,long double的大小为8,因此您希望将它们存储在8的倍数的地址中 - 但前三个变量是整数,形成12,所以在长双精度的第一个定义块全部存储在非对齐的内存地址中。

第二块定义似乎并不太相似 - 但bool已向上移动,使TUV现在完全一致。如果TUV是算法中使用最多的内存,那么我很可能会认为存在时序差异!

那么你如何解决它?要么告诉编译器以更大的对齐方式存储变量(注意这是与打包有关 - 与结构中的存储有关),或者至少放入所有最大类型的变量变量首先在声明中。

答案 1 :(得分:0)

user5108_Dan说:

  

关于优化器,我的意思是我只是使用默认的编译器设置。我可以更改任何数组长度并影响速度,或者我可以添加虚拟变量来影响速度。

这很可能是你的问题。由于生产代码将始终进行优化,因此不要对未经优化的代码进行速度测试:基本上您将完成编译器的工作!