March 6th, 2020

Analyze your builds programmatically with the C++ Build Insights SDK

Kevin Cadieux
Software Engineer

We’re happy to announce today the release of the C++ Build Insights SDK, a framework that gives you access to MSVC build time information via C and C++ APIs. To accompany this release, we are making vcperf open source on GitHub. Because vcperf itself is built with the SDK, you can use it as a reference when developing your own tools. We’re excited to see what sort of applications you’ll be building with the SDK, and we’re looking forward to receiving your feedback!

Background

Last November, we introduced vcperf and its Windows Performance Analyzer (WPA) plugin to help MSVC users understand their build times. Both components were announced under the umbrella of C++ Build Insights. But what is C++ Build Insights, really?

We’ve already covered in November that C++ Build Insights is based on Event Tracing for Windows (ETW), the convenient tracing mechanism available in the Windows operating system. But for our technology to scale to the very large C++ builds done by our customers, ETW wasn’t enough. We needed to fine-tune the event model and analysis algorithms used. This work resulted in a new data analysis platform for MSVC that we now call C++ Build Insights.

Today, the C++ Build Insights platform is what powers vcperf and some of our internal tools. However, we wanted to give all of you the opportunity to benefit from it, too. To this end, we packaged it up behind C and C++ interfaces to create a full-fledged software development kit.

Get started with the C++ Build Insights SDK

Use the C++ Build Insights SDK to build custom tools that fit your scenarios:

  1. Analyze traces programmatically rather than through WPA.
  2. Add build time analysis into your continuous integration (CI).
  3. Or just have fun!

Here is how you can get started with the SDK. This example shows how to build a program that lists all functions taking more than 500 milliseconds to generate.

Capturing a trace with vcperf. Use the /stopnoanalyze command to obtain a trace that is compatible with the C++ Build Insights SDK.

  1. Download and install a copy of Visual Studio 2019.
  2. Obtain a trace of your build.
    1. Launch an x64 Native Tools Command Prompt for VS 2019.
    2. Run the following command: vcperf /start MySessionName
    3. Build your C++ project from anywhere, even from within Visual Studio (vcperf collects events system-wide).
    4. Run the following command: vcperf /stopnoanalyze MySessionName outputFile.etl. This will save a trace of your build in outputFile.etl.
  3. Launch Visual Studio and create a new C++ project.
  4. Right-click on your project’s name, select Manage NuGet packages… and install the latest Microsoft.Cpp.BuildInsights NuGet package from the official nuget.org feed. You will be prompted to accept the license.
  5. Type in the following code.
  6. Build and run by passing the path to outputFile.etl as the first argument.
#include <iostream>
#include <CppBuildInsights.hpp>

using namespace Microsoft::Cpp::BuildInsights;
using namespace Activities;

class LongCodeGenFinder : public IAnalyzer
{
public:
    // Called by the analysis driver every time an activity stop event
    // is seen in the trace. 
    AnalysisControl OnStopActivity(const EventStack& eventStack) override
    {
        // This will check whether the event stack matches
        // TopFunctionsFinder::CheckForTopFunction's signature.
        // If it does, it will forward the event to the function.

        MatchEventStackInMemberFunction(eventStack, this, 
            &LongCodeGenFinder::CheckForLongFunctionCodeGen);

        // Tells the analysis driver to proceed to the next event

        return AnalysisControl::CONTINUE;
    }

    // This function is used to capture Function activity events that are 
    // within a CodeGeneration activity, and to print a list of functions 
    // that take more than 500 milliseconds to generate.

    void CheckForLongFunctionCodeGen(CodeGeneration cg, Function f)
    {
        using namespace std::chrono;

        if (f.Duration() < milliseconds(500)) {
            return;
        }

        std::cout << "Duration: " << duration_cast<milliseconds>(
            f.Duration()).count();

        std::cout << "\t Function Name: " << f.Name() << std::endl;
    }
};

int main(int argc, char *argv[])
{
    if (argc <= 1) return -1;

    LongCodeGenFinder lcgf;

    // Let's make a group of analyzers that will receive
    // events in the trace. We only have one; easy!
    auto group = MakeStaticAnalyzerGroup(&lcgf);

    // argv[1] should contain the path to a trace file
    int numberOfPasses = 1;
    return Analyze(argv[1], numberOfPasses, group);
}

A cloneable and buildable version of this sample is also available on our C++ Build Insights samples GitHub repository.

Note that it’s also possible to obtain a trace programmatically instead of through vcperf by using the SDK. See the official C++ Build Insights SDK documentation for details.

vcperf is now open source

vcperf itself is built using the C++ Build Insights SDK, and we are making it open-source today on GitHub. We hope you will be able to use it to learn more about the SDK, and to customize vcperf to your own needs. The repository includes an example commit that extends vcperf to detect linkers that were restarted due to error conditions. The example highlights these invocations in C++ Build Insights’ Build Explorer view in WPA. We recommend reading this sample commit in the following order:

  1. RestartedLinkerDetector.h
  2. BuildExplorerView.cpp
  3. Commands.cpp

A reason why you might want to build and run vcperf from GitHub today is to gain access to new events that are not yet supported in the released version of vcperf, including the new template instantiation events. Note that vcperf is not tied to any particular version of Visual Studio, but that the new events are only supported in Visual Studio 2019 version 16.4 and above. Here is the updated event table:

Updated event table for the latest version of C++ Build Insights. New events include template instantiation times and force-inlined functions.

Tell us what you think!

We hope you will enjoy the release of the C++ Build Insights SDK, as well as the open-source version of vcperf. Download Visual Studio 2019 today and get started on your first C++ Build Insights application.

In this article, we shared a simple example on how to use the SDK to identify functions taking a long time to generate in your entire build. We also pointed you to useful resources for customizing vcperf. Stay tuned for more examples and code samples in future blog posts!

Would you like the SDK to support additional events? What are some of the ways you have customized vcperf to your needs? Please let us know in the comments below, on Twitter (@VisualC), or via email at visualcpp@microsoft.com.

Author

Kevin Cadieux
Software Engineer

Engineer working on MSVC.

5 comments

Discussion is closed. Login to edit/delete existing comments.

  • Jon Fetter-Degges

    I’m excited to use this – but I’ve been unable to find the results for template instantiation. I’ve been using the open source version of vcperf, and building with both VS 16.4 and 16.5 Preview.

    I’ve been starting with vcperf.exe /start /level3 session, then building, then stopping with vcperf.exe /stop /templates session output.etl.

    Any suggestions? Where should template times appear in Windows Performance Analyzer?

    • Kevin CadieuxMicrosoft employee Author

      Hi Jon,

      Did you copy over the perf_msvcbuildinsights.dll from the NuGet package to your WPA installation? The steps for this are described in the vcperf README on GitHub. If you have done that but it still doesn't work, consider the following options:

      - Try enabling the Templates Instantiation view in WPA as described in this tutorial. The tutorial doesn't mention the Templates Instantiations view because it wasn't released yet but the steps to enable it are the...

      Read more
      • Scott Hutchinson

        I have template instantiation events enabled, but I cannot find them in WPA. I see only the other three events. And our 1.5-million line solution has the code “template<typename" more than 8,600 times.

        And yes I used /level3.

        I guess I cannot post screenshots in this editor to show what I have described?

        EDIT: I built our “solution under test” with VS 2017. Could that be the problem?

        Any other suggestions?

        Thanks,
        Scott

      • Kevin CadieuxMicrosoft employee Author

        Hi Scott,

        While vcperf supports earlier versions of Visual Studio down to 2017, it will only show the events that are actually emitted by the version of VS that you are using. Template events in particular are only emitted in Visual Studio 2019 version 16.4 and above. So you were right: using VS 2017 is most likely the cause. It should work if you upgrade to the latest version of VS 2019. Please let me know...

        Read more
      • Jon Fetter-Degges

        Thank you, updating perf_msvcbuildinsights.dll from the NuGet package worked. Always good to read all the documentation!