编译器优化如何影响数据加载速度? 我测试了三个C++程序代码,将数据从内存加载到CPU,做简单+或X操作(计算时间),然后报告结果。这三种代码的结构相同,但数据类型不同(int、double、float)

编译器优化如何影响数据加载速度? 我测试了三个C++程序代码,将数据从内存加载到CPU,做简单+或X操作(计算时间),然后报告结果。这三种代码的结构相同,但数据类型不同(int、double、float),c++,performance,C++,Performance,测试结果是:当三个代码的数据大小均为2x时,时间为2x 然而,我有以下观察 观察1:不使用优化时,时间慢2倍。然而,这很奇怪,因为加载时间(瓶颈)不应该受到编译器的影响 观察结果2:在不添加编译器优化且数据大小固定(256MB、512MB、1024MB、2048MB、4096MB)的情况下,双类型程序代码的时间大约比int和float类型程序代码快2倍。这也很奇怪,因为double应该是最慢的一个 观察2的备注:当我添加编译器优化(O,O2,O3)时,这三个代码的时间是相似的 附件代码如下: i

测试结果是:当三个代码的数据大小均为2x时,时间为2x

然而,我有以下观察

观察1:不使用优化时,时间慢2倍。然而,这很奇怪,因为加载时间(瓶颈)不应该受到编译器的影响

观察结果2:在不添加编译器优化且数据大小固定(256MB、512MB、1024MB、2048MB、4096MB)的情况下,双类型程序代码的时间大约比int和float类型程序代码快2倍。这也很奇怪,因为double应该是最慢的一个

观察2的备注:当我添加编译器优化(O,O2,O3)时,这三个代码的时间是相似的

附件代码如下:

int main()
{
     float value;
     double totalTimeDifference;

     const int numberOFElements=178956970; //4GB for 6 arrays in total 
     float*FLOAT_Array_one=new float[numberOFElements];
     float*FLOAT_Array_two=new float[numberOFElements];
     float*FLOAT_Array_three=new float[numberOFElements];
     float*FLOAT_Array_four=new float[numberOFElements];
     float*FLOAT_Array_five=new float[numberOFElements];
     float*FLOAT_Array=new float[numberOFElements];

     srand(time(NULL));
     for(int i=0;i<numberOFElements;i++)
     {
         FLOAT_Array_one[i]=rand()% 400;
         FLOAT_Array_two[i]=rand()% 400;
         FLOAT_Array_four[i]=rand()% 400;
         FLOAT_Array_five[i]=rand()% 400;
     }

     timeval tim1;
     timeval tim2;
     gettimeofday(&tim1,NULL);

     //****************************//
     for(int i=0;i<numberOFElements;i++)
     {
         FLOAT_Array[i]=FLOAT_Array_one[i]+FLOAT_Array_two[i];
     }
     //****************************//

     //****************************//
     for(int i=0;i<numberOFElements;i++)
     {
         FLOAT_Array_three[i]=FLOAT_Array_four[i]*FLOAT_Array_five[i];
     }
     //****************************//
     gettimeofday(&tim2,NULL);

     double t1=tim1.tv_sec+(tim1.tv_usec/1000000.0);
     double t2=tim2.tv_sec+(tim2.tv_usec/1000000.0);

     for(int i=0;i<numberOFElements;i++)
     {
         if(i%2==0)
             value=value+FLOAT_Array[i]+FLOAT_Array_three[i];
         else
             value=value-FLOAT_Array[i]-FLOAT_Array_three[i];
     }

     totalTimeDifference=t2-t1; 
     cout<<value<<endl;
     cout<<totalTimeDifference<<endl;
}
intmain()
{
浮动值;
双总时差;
const int numberOFElements=178956970;//4GB,共6个数组
float*float_Array_one=新的float[numberOFElements];
float*float_Array_two=新的float[numberOFElements];
float*float_Array_three=新的float[numberOFElements];
float*float_Array_four=新的float[numberOFElements];
float*float_Array_five=新的float[numberOFElements];
float*float_数组=新的float[numberOFElements];
srand(时间(空));

对于(int i=0;i一些有根据的猜测:

  • 由于您在两次时间检查之间的“加载”过程中进行算术运算,因此可能只有在优化时才使用SSE流式浮点数学指令。这将导致显著的加速
  • 如果您在64位操作系统上,两个半字的内存访问比一个整字的内存访问需要更多的时间。在64位程序上,浮点运算只需要32位,后续对半字的访问比单个整字的访问需要更多的时间。然而,我不理解的部分是优化如何绕过这一点

  • 细节中有魔鬼。在看不到代码(并对生成的程序集进行探测)的情况下,我们只能对实际发生的情况进行胡乱猜测。非优化代码的计时是无趣的,因为您告诉编译器“不要费心让它变快”。因此它不会,并且程序可能包含大量不必要的代码。。我在这里添加了代码。这是浮点版本。加载速度受-O0的影响,因为将有更多的存储和加载(到堆栈/从堆栈中加载,在堆栈中它将放置所有局部变量,而不是分配寄存器)