【发布时间】:2018-05-12 12:02:38
【问题描述】:
当大量代码被编译器内联时,如何理解 Windows 上的 C++ 分析数据? IE。我当然想测量实际运行的代码,所以根据定义,我将测量代码的优化构建。但似乎我尝试的任何工具都无法真正解决内联函数。
我在 Visual Studio 2017 Professional 和 VTune 2018 中都尝试过采样分析器。我尝试启用 /Zo,但似乎没有任何影响。
我发现以下资源似乎表明只有 Visual Studio Ultimate 或 Premium 支持内联框架信息 - Visual Studio 2017 仍然如此吗? https://social.msdn.microsoft.com/Forums/en-US/9df15363-5aae-4f0b-a5ad-dd9939917d4c/which-functions-arent-pgo-optimized-using-profile-data?forum=vsdebug
这是一个示例代码:
#include <cmath>
#include <random>
#include <iostream>
inline double burn()
{
std::uniform_real_distribution<double> uniform(-1E5, 1E5);
std::default_random_engine engine;
double s = 0;
for (int i = 0; i < 100000000; ++i) {
s += uniform(engine);
}
return s;
}
int main()
{
std::cout << "random sum: " << burn() << '\n';
return 0;
}
在发布模式下使用 Visual Studio 编译它。或者在命令行上尝试cl /O2 /Zi /Zo /EHsc main.cpp。然后尝试使用 Visual Studio 中的 CPU Sampling Profiler 对其进行分析。你最多会看到这样的东西:
VTune 2018 在 Windows 上看起来很相似。在 Linux 上,perf 和 VTune 可以毫无问题地显示内联函数的帧……这个在我看来对 C++ 工具至关重要的功能真的不属于非高级/终极 Visual Studio 工具链的一部分吗? Windows 上的人如何处理这个问题?那/Zo有什么意义呢?
编辑:我只是尝试用 clang 编译上面的最小示例,它产生了不同但仍然不令人满意的结果?我编译了 clang 6.0.0(主干),从 LLVM rev 318844 和 clang rev 318874 构建。然后我使用 clang++ -std=c++17 -O2 -g main.cpp -o main.exe 编译我的代码,并再次使用 Visual Studio 中的 Sampling Profiler 运行生成的可执行文件,结果是:
所以现在我看到了burn 函数,但是丢失了源文件信息。此外,uniform_real_distribution 仍然没有显示在任何地方。
编辑 2: 正如 cmets 中所建议的,我现在还尝试了 clang-cl,其参数与上述 cl 相同,即:clang-cl.exe /O2 /Zi /Zo /EHsc main.cpp。这产生了与clang.exe 相同的结果,但我们也得到了一些有效的源映射:
编辑 3: 我原本以为 clang 会神奇地解决这个问题。可悲的是,它没有。大多数内联帧仍然丢失:(
编辑 4: VTune 不支持使用 MSVC/PDB 构建的应用程序构建的内联框架:https://software.intel.com/en-us/forums/intel-vtune-amplifier-xe/topic/749363
【问题讨论】:
-
基于此文档:visualstudio.com/vs/compare,当前的 VS2017 版本支持性能和诊断中心功能,现在没有 VS2017 Premium/Ultimate。如果您真的想知道结果,我可以设置不同的 VS 环境并稍后对其进行测试,但很抱歉,我不太确定您如何分析您的应用程序并解决此问题,例如您身边的第二个屏幕截图。如果我们想分析您的应用程序,据我所知,有两种方法,使用 VS IDE 或分析命令行。你的意思是你使用其他工具或命令行?
-
@JackZhai-MSFT 是的,CPU 分析器在 VS 2017 中可用。似乎不可用的是显示内联帧的功能。另请参阅:blogs.msdn.microsoft.com/vcblog/2013/06/27/… 这在 Visual Studio 2017 中根本不起作用
-
您可以尝试使用clang-cl(或clang.exe --driver-mode=cl)并将您传递给cl的相同参数传递给cl,看看会发生什么?如果它仍然有效,那么我们就会知道我们不会错过一些可以解决此问题的神奇 cl 选项
标签: c++ visual-studio profiling inline visual-studio-debugging