Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 删除代码部分与探查器';s数据_C++_Optimization_Profiler - Fatal编程技术网

C++ 删除代码部分与探查器';s数据

C++ 删除代码部分与探查器';s数据,c++,optimization,profiler,C++,Optimization,Profiler,我正在做一个小的概念验证概要文件和优化示例类型。然而,我遇到了一些我无法解释的事情,我希望这里有人能澄清这一点 我写了一段很短的代码: int main (void) { for (int j = 0; j < 1000; j++) { a = 1; b = 2; c = 3; for (int i = 0; i < 100000; i++) { callback

我正在做一个小的概念验证概要文件和优化示例类型。然而,我遇到了一些我无法解释的事情,我希望这里有人能澄清这一点

我写了一段很短的代码:

int main (void)
{
    for (int j = 0; j < 1000; j++)
    {
        a = 1;
        b = 2;
        c = 3;

        for (int i = 0; i < 100000; i++)
        {
            callbackWasterOne();
            callbackWasterTwo();
        }
        printf("Two a: %d, b: %d, c: %d.", a, b, c);
    }
    return 0;
}

void callbackWasterOne(void)
{
    a = b * c;
}
void callbackWasterTwo(void)
{
    b = a * c;
}
int main(无效)
{
对于(int j=0;j<1000;j++)
{
a=1;
b=2;
c=3;
对于(int i=0;i<100000;i++)
{
甾酮();
callbackastertwo();
}
printf(“两个a:%d,b:%d,c:%d.”,a,b,c);
}
返回0;
}
无效甾酮(无效)
{
a=b*c;
}
无效呼叫回水二(无效)
{
b=a*c;
}
它所做的只是调用两个非常基本的函数,将数字相乘。由于代码是相同的,我希望探查器(oprofile)返回大致相同的数字

我在每个配置文件中运行此代码10次,并得到每个函数所用时间的以下值:

  • 主要:平均值=5.60%,标准差=0.10%
  • Callbackasterone=43.78%,stdev=1.04%
  • Callbackastertwo=50.24%,stdev=0.98%
  • rest是各种各样的东西,比如printf和no-vmlinux
Callbackasterone和Callbackastertwo的时间差足够大(至少对我来说),因为它们有相同的代码,所以我在代码中切换了它们的顺序,并重新运行探查器,结果如下:

  • 主要:平均值=5.45%,标准差=0.40%
  • Callbackasterone=50.69%,stdev=0.49%
  • Callbackastertwo=43.54%,stdev=0.18%
  • rest是各种各样的东西,比如printf和no-vmlinux
因此,显然探查器会根据执行顺序对一个进行采样,而不是对另一个进行采样。不好的。忽略这一点,我决定看看删除一些代码的效果,我得到了执行时间(平均值):

  • 未删除任何内容:0.5295秒
  • 已从for循环0.2075s中删除对callbackasterone()的调用
  • 已从for循环0.2042s中删除对callbackastertwo()的调用
  • 从for循环中删除两个调用:0.1903s
  • 删除两个调用和for循环:0.0025s
  • 去除Callbackasterone的含量:0.379s
  • 清除Callbackastertwo的内容物:0.378s
  • 删除两个:0.382s的内容
以下是我难以理解的问题:

  • 当我从for循环中删除一个调用时,执行时间会下降约60%,这比一个函数+main所花费的时间还要长!这怎么可能
  • 为什么从循环中删除两个调用的效果比只删除一个调用的效果要小?我无法理解这种非线性。我知道for循环是昂贵的,但是在这种情况下(如果剩余的大部分时间都可以归因于执行函数调用的for循环),那么为什么删除其中一个调用首先会导致如此大的改进呢
我查看了反汇编,这两个函数在代码上是相同的。对它们的调用是相同的,删除调用只会删除一条调用线

其他可能相关的信息

  • 我使用的是Ubuntu 14.04LTS
  • 该代码由Eclipse编写,无需优化(O0)
  • 我通过在终端中使用“time”运行代码来计时
  • 我使用计数为10000且重复10次的OProfile
以下是我使用
-O1
优化时得到的结果:

  • 主要指标:平均值=5.89%,标准差=0.14%
  • Callbackasterone:avg=44.28%,stdev=2.64%
  • Callbackastertwo:avg=49.66%,stdev=2.54%(比以前大)
  • 其余的都是杂七杂八的
删除各种位的结果(执行时间平均值):

  • 未删除任何内容:0.522s
  • 去除callbackasterone call:0.149s(减少71.47%)
  • 删除调用backastertwo调用:0.123%(减少76.45%)
  • 删除两个调用:0.0365秒(减少93.01%)(鉴于上面的配置文件数据,这是我所期望的)
因此,现在删除一个调用要比以前好得多,同时删除两个调用仍然有好处(可能是因为优化器知道循环中不会发生任何事情)。尽管如此,删除一个比我预期的更有益

使用不同变量的两个函数的结果: 我为callbackastertwo()定义了另外3个变量,以代替重复使用相同的变量。现在的结果正是我所期望的

  • 主要:平均值=10.87%,标准差=0.19%(平均值更高,但可能是由于这些新变量)
  • Callbackasterone:avg=46.08%,stdev=0.53%
  • Callbackastertwo:平均值=42.82%,标准差=0.62%
  • 其余的都是杂七杂八的
删除各种位的结果(执行时间平均值):

  • 未删除任何内容:0.520秒
  • 去除callbackasterone call:0.292s(减少43.83%)
  • 删除调用backastertwo调用:0.291%(减少44.07%)
  • 删除两个呼叫:0.065s(减少87.55%)
所以现在删除两个调用相当于(在stdev中)删除一个调用+另一个调用。 由于删除任何一个函数的结果几乎相同(43.83%对44.07%),所以我要说的是,可能探查器的数据(46%对42%)仍然是倾斜的。也许这就是它采样的方式(接下来将改变计数器值,看看会发生什么)

看来,优化的成功与代码重用率密切相关。实现分析器所指出的“精确”(你知道我的意思)加速的唯一方法是在完全独立的代码上进行优化。无论如何,这一切都很有趣

我仍然在为
-O1
案例中70%的下降寻找一些解释思路