我有一个原生C ++应用程序,它执行大量计算并消耗大量内存。我的目标是优化它,主要是减少它的运行时间 经过几轮分析优化后,我尝试了以前从未尝试过的 Profile Guided Optimization 。
我按照MSDN Profile-Guided Optimizations上描述的步骤,更改了编译(/GL
)和链接(/LTCG
)标记。添加/GENPROFILE
后,我运行应用程序以创建.pgc
和.pdg
文件,然后将链接器选项更改为/USEPROFILE
并观察其他链接器消息,这些消息报告分析数据为使用:
3> 0 of 0 ( 0.0%) original invalid call sites were matched.
3> 0 new call sites were added.
3> 116 of 27096 ( 0.43%) profiled functions will be compiled for speed, and the rest of the functions will be compiled for size
3> 63583 of 345025 inline instances were from dead/cold paths
3> 27096 of 27096 functions (100.0%) were optimized using profile data
3> 608324578581 of 608324578581 instructions (100.0%) were optimized using profile data
3> Finished generating code
一切看起来很有希望,直到我测量了程序的性能。
性能下降而不是上升!比未使用配置文件引导优化(与使用/不使用/USEPROFILE
选项进行比较时)4%至5%更慢。
即使运行与/GENPROFILE
一起使用的完全相同的方案来创建配置文件引导优化数据文件,它也会慢4%。
发生了什么事?
答案 0 :(得分:1)
查看稀疏文档 here,分析器似乎没有包含任何内存优化。
如果您的程序占用 2GiB 内存,我推测执行速度受内存访问而不是 CPU 本身的限制。 (您还说明了有关正在使用的地图的内容,这些也受内存限制) 内存访问很难针对分析器进行优化,因为它无法更改您的 malloc 调用以(例如)将常用数据放入相同页面或确保它们移动到 CPU 的相同缓存行。
此外,在尝试优化程序的裸 CPU 性能时,分析器可能会引入额外的内存访问。 该文档指出“虚拟调用推测”,我推测这(可能还有内联等其他功能)可能引入额外的内存流量,从而降低整体性能,因为内存带宽已经是限制因素。< /p>
答案 1 :(得分:-4)
这些东西会隐藏在配置文件引导或任何其他优化器中,它们肯定会隐藏在你的猜测器之外。
他们不会躲避this。很多人都使用它。
我试图抵制猜测的诱惑,但我失败了。 这就是我在大C ++应用程序中看到的内容,无论它们写得多么好。 当人们可以使用像数组这样的简单数据结构时,他们会使用抽象容器类,迭代器和诸如此类的东西。时间到了哪里? 那就是。
他们做的另一件事是编写强大的功能和方法&#34;。该函数的作者为此感到骄傲,它做得如此之多,以至于他/她期望它会被虔诚和谨慎地称为。
该功能的用户(可能是同一个人)认为&#34;看看这个功能有多么有用!看看我能用一行代码完成多少工作?我使用的越多,我的生产力就越高。&#34;
看看这可以轻松做出不必要的工作吗?
软件中还有另一件事 - 抽象层。
如果上面的模式在几个抽象层上重复,则减速因子成倍增加
好消息是,如果你能找到它们,如果你能解决它们,你就可以获得巨大的加速。坏消息是你可能会受到影响而不是团队成员#34;。