forked from microsoft/cpp-build-insights-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request microsoft#7 from kevcadieux/function-bottleneck-sa…
…mple Function bottleneck sample
- Loading branch information
Showing
6 changed files
with
392 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<ItemGroup Label="ProjectConfigurations"> | ||
<ProjectConfiguration Include="Debug|Win32"> | ||
<Configuration>Debug</Configuration> | ||
<Platform>Win32</Platform> | ||
</ProjectConfiguration> | ||
<ProjectConfiguration Include="Release|Win32"> | ||
<Configuration>Release</Configuration> | ||
<Platform>Win32</Platform> | ||
</ProjectConfiguration> | ||
<ProjectConfiguration Include="Debug|x64"> | ||
<Configuration>Debug</Configuration> | ||
<Platform>x64</Platform> | ||
</ProjectConfiguration> | ||
<ProjectConfiguration Include="Release|x64"> | ||
<Configuration>Release</Configuration> | ||
<Platform>x64</Platform> | ||
</ProjectConfiguration> | ||
</ItemGroup> | ||
<PropertyGroup Label="Globals"> | ||
<VCProjectVersion>16.0</VCProjectVersion> | ||
<ProjectGuid>{F002C795-7D92-4146-8A7C-BBEB946F4309}</ProjectGuid> | ||
<RootNamespace>FunctionBottlenecks</RootNamespace> | ||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||
<ProjectName>FunctionBottlenecks</ProjectName> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>true</UseDebugLibraries> | ||
<PlatformToolset>v142</PlatformToolset> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>false</UseDebugLibraries> | ||
<PlatformToolset>v142</PlatformToolset> | ||
<WholeProgramOptimization>true</WholeProgramOptimization> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>true</UseDebugLibraries> | ||
<PlatformToolset>v142</PlatformToolset> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>false</UseDebugLibraries> | ||
<PlatformToolset>v142</PlatformToolset> | ||
<WholeProgramOptimization>true</WholeProgramOptimization> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
<ImportGroup Label="ExtensionSettings"> | ||
</ImportGroup> | ||
<ImportGroup Label="Shared"> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<PropertyGroup Label="UserMacros" /> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<LinkIncremental>true</LinkIncremental> | ||
<OutDir>$(SolutionDir)out\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<LinkIncremental>true</LinkIncremental> | ||
<OutDir>$(SolutionDir)out\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<LinkIncremental>false</LinkIncremental> | ||
<OutDir>$(SolutionDir)out\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||
<LinkIncremental>false</LinkIncremental> | ||
<OutDir>$(SolutionDir)out\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> | ||
</PropertyGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<ClCompile> | ||
<WarningLevel>Level3</WarningLevel> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<ClCompile> | ||
<WarningLevel>Level3</WarningLevel> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<ClCompile> | ||
<WarningLevel>Level3</WarningLevel> | ||
<FunctionLevelLinking>true</FunctionLevelLinking> | ||
<IntrinsicFunctions>true</IntrinsicFunctions> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | ||
<OptimizeReferences>true</OptimizeReferences> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||
<ClCompile> | ||
<WarningLevel>Level3</WarningLevel> | ||
<FunctionLevelLinking>true</FunctionLevelLinking> | ||
<IntrinsicFunctions>true</IntrinsicFunctions> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | ||
<OptimizeReferences>true</OptimizeReferences> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemGroup> | ||
<ClCompile Include="main.cpp" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="packages.config" /> | ||
</ItemGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
<ImportGroup Label="ExtensionTargets"> | ||
<Import Project="..\packages\Microsoft.Cpp.BuildInsights.1.1.0\build\native\Microsoft.Cpp.BuildInsights.targets" Condition="Exists('..\packages\Microsoft.Cpp.BuildInsights.1.1.0\build\native\Microsoft.Cpp.BuildInsights.targets')" /> | ||
</ImportGroup> | ||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | ||
<PropertyGroup> | ||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | ||
</PropertyGroup> | ||
<Error Condition="!Exists('..\packages\Microsoft.Cpp.BuildInsights.1.1.0\build\native\Microsoft.Cpp.BuildInsights.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Cpp.BuildInsights.1.1.0\build\native\Microsoft.Cpp.BuildInsights.targets'))" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<ItemGroup> | ||
<Filter Include="Source Files"> | ||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||
</Filter> | ||
<Filter Include="Header Files"> | ||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> | ||
</Filter> | ||
<Filter Include="Resource Files"> | ||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||
</Filter> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ClCompile Include="main.cpp"> | ||
<Filter>Source Files</Filter> | ||
</ClCompile> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="packages.config" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
#include <algorithm> | ||
#include <iomanip> | ||
#include <iostream> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <vector> | ||
#include <CppBuildInsights.hpp> | ||
|
||
using namespace Microsoft::Cpp::BuildInsights; | ||
using namespace Activities; | ||
using namespace SimpleEvents; | ||
|
||
class FunctionBottlenecks : public IAnalyzer | ||
{ | ||
struct IdentifiedFunction | ||
{ | ||
std::string Name; | ||
std::chrono::milliseconds Duration; | ||
double Percent; | ||
unsigned ForceInlineeSize; | ||
|
||
bool operator<(const IdentifiedFunction& other) const { | ||
return Duration > other.Duration; | ||
} | ||
}; | ||
|
||
public: | ||
FunctionBottlenecks(): | ||
pass_{0}, | ||
cachedInvocationDurations_{}, | ||
identifiedFunctions_{}, | ||
forceInlineSizeCache_{} | ||
{} | ||
|
||
AnalysisControl OnBeginAnalysisPass() override | ||
{ | ||
++pass_; | ||
return AnalysisControl::CONTINUE; | ||
} | ||
|
||
AnalysisControl OnStopActivity(const EventStack& eventStack) | ||
override | ||
{ | ||
switch (pass_) | ||
{ | ||
case 1: | ||
MatchEventStackInMemberFunction(eventStack, this, | ||
&FunctionBottlenecks::OnStopInvocation); | ||
break; | ||
|
||
case 2: | ||
MatchEventStackInMemberFunction(eventStack, this, | ||
&FunctionBottlenecks::OnStopFunction); | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
|
||
return AnalysisControl::CONTINUE; | ||
} | ||
|
||
AnalysisControl OnSimpleEvent(const EventStack& eventStack) | ||
{ | ||
if (pass_ > 1) { | ||
return AnalysisControl::CONTINUE; | ||
} | ||
|
||
MatchEventStackInMemberFunction(eventStack, this, | ||
&FunctionBottlenecks::ProcessForceInlinee); | ||
|
||
return AnalysisControl::CONTINUE; | ||
} | ||
|
||
void OnStopInvocation(Invocation invocation) | ||
{ | ||
using namespace std::chrono; | ||
|
||
// Ignore very short invocations | ||
if (invocation.Duration() < std::chrono::seconds(1)) { | ||
return; | ||
} | ||
|
||
cachedInvocationDurations_[invocation.EventInstanceId()] = | ||
duration_cast<milliseconds>(invocation.Duration()); | ||
} | ||
|
||
void OnStopFunction(Invocation invocation, Function func) | ||
{ | ||
using namespace std::chrono; | ||
|
||
auto itInvocation = cachedInvocationDurations_.find( | ||
invocation.EventInstanceId()); | ||
|
||
if (itInvocation == cachedInvocationDurations_.end()) { | ||
return; | ||
} | ||
|
||
auto itForceInlineSize = forceInlineSizeCache_.find( | ||
func.EventInstanceId()); | ||
|
||
unsigned forceInlineSize = | ||
itForceInlineSize == forceInlineSizeCache_.end() ? | ||
0 : itForceInlineSize->second; | ||
|
||
milliseconds functionMilliseconds = | ||
duration_cast<milliseconds>(func.Duration()); | ||
|
||
double functionTime = static_cast<double>( | ||
functionMilliseconds.count()); | ||
|
||
double invocationTime = static_cast<double>( | ||
itInvocation->second.count()); | ||
|
||
double percent = functionTime / invocationTime; | ||
|
||
if (percent > 0.05 && func.Duration() >= seconds(1)) | ||
{ | ||
identifiedFunctions_[func.EventInstanceId()]= | ||
{ func.Name(), functionMilliseconds, percent, | ||
forceInlineSize }; | ||
} | ||
} | ||
|
||
void ProcessForceInlinee(Function func, ForceInlinee inlinee) | ||
{ | ||
forceInlineSizeCache_[func.EventInstanceId()] += | ||
inlinee.Size(); | ||
} | ||
|
||
AnalysisControl OnEndAnalysis() override | ||
{ | ||
std::vector<IdentifiedFunction> sortedFunctions; | ||
|
||
for (auto& p : identifiedFunctions_) { | ||
sortedFunctions.push_back(p.second); | ||
} | ||
|
||
std::sort(sortedFunctions.begin(), sortedFunctions.end()); | ||
|
||
for (auto& func : sortedFunctions) | ||
{ | ||
bool forceInlineHeavy = func.ForceInlineeSize >= 10000; | ||
|
||
std::string forceInlineIndicator = forceInlineHeavy ? | ||
", *" : ""; | ||
|
||
int percent = static_cast<int>(func.Percent * 100); | ||
|
||
std::string percentString = "(" + | ||
std::to_string(percent) + "%" + | ||
forceInlineIndicator + ")"; | ||
|
||
std::cout << std::setw(9) << std::right << | ||
func.Duration.count(); | ||
std::cout << " ms "; | ||
std::cout << std::setw(9) << std::left << | ||
percentString; | ||
std::cout << " " << func.Name << std::endl; | ||
} | ||
|
||
return AnalysisControl::CONTINUE; | ||
} | ||
|
||
private: | ||
unsigned pass_; | ||
|
||
std::unordered_map<unsigned long long, | ||
std::chrono::milliseconds> cachedInvocationDurations_; | ||
|
||
std::unordered_map<unsigned long long, | ||
IdentifiedFunction> identifiedFunctions_; | ||
|
||
std::unordered_map<unsigned long long, | ||
unsigned> forceInlineSizeCache_; | ||
}; | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
if (argc <= 1) return -1; | ||
|
||
std::cout.imbue(std::locale("")); | ||
|
||
FunctionBottlenecks fb; | ||
|
||
auto group = MakeStaticAnalyzerGroup(&fb); | ||
|
||
// argv[1] should contain the path to a trace file | ||
int numberOfPasses = 2; | ||
return Analyze(argv[1], numberOfPasses, group); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<packages> | ||
<package id="Microsoft.Cpp.BuildInsights" version="1.1.0" targetFramework="native" /> | ||
</packages> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.