diff options
| author | Yong He <yonghe@outlook.com> | 2023-07-11 09:29:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-11 09:29:27 -0700 |
| commit | d0901aa7933ac31b0bf7648a31ec5c13de864457 (patch) | |
| tree | 298db796f1200013e841ed03db7ca24e2890c00a | |
| parent | d9c57e613f2dacd221d9c46c10395cf373a8fcaf (diff) | |
Add perf benchmark utility. (#2977)
* Add perf benchmark utility.
* Update documentation.
* Fix.
* Fix doc.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
| -rw-r--r-- | build/visual-studio/core/core.vcxproj | 2 | ||||
| -rw-r--r-- | build/visual-studio/core/core.vcxproj.filters | 6 | ||||
| -rw-r--r-- | build/visual-studio/slang-rt/slang-rt.vcxproj | 2 | ||||
| -rw-r--r-- | build/visual-studio/slang-rt/slang-rt.vcxproj.filters | 6 | ||||
| -rw-r--r-- | docs/command-line-slangc-reference.md | 5 | ||||
| -rw-r--r-- | slang.h | 3 | ||||
| -rw-r--r-- | source/core/slang-performance-profiler.cpp | 52 | ||||
| -rw-r--r-- | source/core/slang-performance-profiler.h | 42 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-autodiff.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-inline.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-link.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-loop-unroll.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-specialize.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-ssa-simplification.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 14 |
21 files changed, 169 insertions, 4 deletions
diff --git a/build/visual-studio/core/core.vcxproj b/build/visual-studio/core/core.vcxproj index 559dde3b4..abecd620a 100644 --- a/build/visual-studio/core/core.vcxproj +++ b/build/visual-studio/core/core.vcxproj @@ -302,6 +302,7 @@ <ClInclude Include="..\..\..\source\core\slang-memory-file-system.h" />
<ClInclude Include="..\..\..\source\core\slang-name-value.h" />
<ClInclude Include="..\..\..\source\core\slang-offset-container.h" />
+ <ClInclude Include="..\..\..\source\core\slang-performance-profiler.h" />
<ClInclude Include="..\..\..\source\core\slang-persistent-cache.h" />
<ClInclude Include="..\..\..\source\core\slang-platform.h" />
<ClInclude Include="..\..\..\source\core\slang-process-util.h" />
@@ -360,6 +361,7 @@ <ClCompile Include="..\..\..\source\core\slang-memory-file-system.cpp" />
<ClCompile Include="..\..\..\source\core\slang-name-value.cpp" />
<ClCompile Include="..\..\..\source\core\slang-offset-container.cpp" />
+ <ClCompile Include="..\..\..\source\core\slang-performance-profiler.cpp" />
<ClCompile Include="..\..\..\source\core\slang-persistent-cache.cpp" />
<ClCompile Include="..\..\..\source\core\slang-platform.cpp" />
<ClCompile Include="..\..\..\source\core\slang-process-util.cpp" />
diff --git a/build/visual-studio/core/core.vcxproj.filters b/build/visual-studio/core/core.vcxproj.filters index 11c689121..607e9451e 100644 --- a/build/visual-studio/core/core.vcxproj.filters +++ b/build/visual-studio/core/core.vcxproj.filters @@ -120,6 +120,9 @@ <ClInclude Include="..\..\..\source\core\slang-offset-container.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\core\slang-performance-profiler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\core\slang-persistent-cache.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -290,6 +293,9 @@ <ClCompile Include="..\..\..\source\core\slang-offset-container.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\core\slang-performance-profiler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\core\slang-persistent-cache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj b/build/visual-studio/slang-rt/slang-rt.vcxproj index ad3136e66..09d27d621 100644 --- a/build/visual-studio/slang-rt/slang-rt.vcxproj +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj @@ -314,6 +314,7 @@ <ClInclude Include="..\..\..\source\core\slang-memory-file-system.h" />
<ClInclude Include="..\..\..\source\core\slang-name-value.h" />
<ClInclude Include="..\..\..\source\core\slang-offset-container.h" />
+ <ClInclude Include="..\..\..\source\core\slang-performance-profiler.h" />
<ClInclude Include="..\..\..\source\core\slang-persistent-cache.h" />
<ClInclude Include="..\..\..\source\core\slang-platform.h" />
<ClInclude Include="..\..\..\source\core\slang-process-util.h" />
@@ -373,6 +374,7 @@ <ClCompile Include="..\..\..\source\core\slang-memory-file-system.cpp" />
<ClCompile Include="..\..\..\source\core\slang-name-value.cpp" />
<ClCompile Include="..\..\..\source\core\slang-offset-container.cpp" />
+ <ClCompile Include="..\..\..\source\core\slang-performance-profiler.cpp" />
<ClCompile Include="..\..\..\source\core\slang-persistent-cache.cpp" />
<ClCompile Include="..\..\..\source\core\slang-platform.cpp" />
<ClCompile Include="..\..\..\source\core\slang-process-util.cpp" />
diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj.filters b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters index a33803e0e..2dcb22999 100644 --- a/build/visual-studio/slang-rt/slang-rt.vcxproj.filters +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters @@ -120,6 +120,9 @@ <ClInclude Include="..\..\..\source\core\slang-offset-container.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\core\slang-performance-profiler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\core\slang-persistent-cache.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -293,6 +296,9 @@ <ClCompile Include="..\..\..\source\core\slang-offset-container.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\core\slang-performance-profiler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\core\slang-persistent-cache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/docs/command-line-slangc-reference.md b/docs/command-line-slangc-reference.md index 16d5b52a2..3fcd7a68c 100644 --- a/docs/command-line-slangc-reference.md +++ b/docs/command-line-slangc-reference.md @@ -238,6 +238,11 @@ Treat the rest of the command line as input files. Reports the time spent in the downstream compiler. +<a id="report-perf-benchmark"></a> +## -report-perf-benchmark +Reports compiler performance benchmark results. + + <a id="source-embed-style-1"></a> ## -source-embed-style @@ -4128,6 +4128,9 @@ namespace slang virtual SLANG_NO_THROW void SLANG_MCALL setReportDownstreamTime(bool value) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) = 0; + + }; #define SLANG_UUID_ICompileRequest ICompileRequest::getTypeGuid() diff --git a/source/core/slang-performance-profiler.cpp b/source/core/slang-performance-profiler.cpp new file mode 100644 index 000000000..f5f74f99d --- /dev/null +++ b/source/core/slang-performance-profiler.cpp @@ -0,0 +1,52 @@ +#include "slang-performance-profiler.h" +#include "slang-dictionary.h" + +namespace Slang +{ + struct FuncProfileInfo + { + int invocationCount = 0; + std::chrono::nanoseconds duration = std::chrono::nanoseconds::zero(); + }; + class PerformanceProfilerImpl : public PerformanceProfiler + { + public: + OrderedDictionary<const char*, FuncProfileInfo> data; + + virtual FuncProfileContext enterFunction(const char* funcName) override + { + auto entry = data.tryGetValue(funcName); + if (!entry) + { + data.add(funcName, FuncProfileInfo()); + entry = data.tryGetValue(funcName); + } + entry->invocationCount++; + FuncProfileContext ctx; + ctx.funcName = funcName; + ctx.startTime = std::chrono::high_resolution_clock::now(); + return ctx; + } + virtual void exitFunction(FuncProfileContext ctx) override + { + auto endTime = std::chrono::high_resolution_clock::now(); + auto duration = endTime - ctx.startTime; + auto entry = data.tryGetValue(ctx.funcName); + entry->duration += duration; + } + virtual void getResult(StringBuilder& out) override + { + for (auto func : data) + { + out << func.key << ": \t"; + out << func.value.invocationCount << "\t" << func.value.duration.count()/1000000 << "\n"; + } + } + }; + + PerformanceProfiler* Slang::PerformanceProfiler::getProfiler() + { + static PerformanceProfilerImpl profiler = PerformanceProfilerImpl(); + return &profiler; + } +} diff --git a/source/core/slang-performance-profiler.h b/source/core/slang-performance-profiler.h new file mode 100644 index 000000000..323940ade --- /dev/null +++ b/source/core/slang-performance-profiler.h @@ -0,0 +1,42 @@ +#ifndef SLANG_CORE_PERFORMANCE_PROFILER_H +#define SLANG_CORE_PERFORMANCE_PROFILER_H + +#include "slang-string.h" +#include <chrono> + +namespace Slang +{ + +struct FuncProfileContext +{ + const char* funcName = nullptr; + std::chrono::time_point<std::chrono::high_resolution_clock> startTime; +}; + +class PerformanceProfiler +{ +public: + virtual FuncProfileContext enterFunction(const char* funcName) = 0; + virtual void exitFunction(FuncProfileContext context) = 0; + virtual void getResult(StringBuilder& out) = 0; +public: + static PerformanceProfiler* getProfiler(); +}; + +struct PerformanceProfilerFuncRAIIContext +{ + FuncProfileContext context; + PerformanceProfilerFuncRAIIContext(const char* funcName) + { + context = PerformanceProfiler::getProfiler()->enterFunction(funcName); + } + ~PerformanceProfilerFuncRAIIContext() + { + PerformanceProfiler::getProfiler()->exitFunction(context); + } +}; + +#define SLANG_PROFILE PerformanceProfilerFuncRAIIContext _profileContext(__func__) +} + +#endif diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 7082eccd7..e6385c76d 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -2646,6 +2646,7 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL setDiagnosticFlags(SlangDiagnosticFlags flags) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoFormat(SlangDebugInfoFormat format) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setReportDownstreamTime(bool value) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) SLANG_OVERRIDE; void setHLSLToVulkanLayoutOptions(int targetIndex, HLSLToVulkanLayoutOptions* vulkanLayoutOptions); EndToEndCompileRequest( @@ -2691,6 +2692,9 @@ namespace Slang bool m_isCommandLineCompile = false; bool m_reportDownstreamCompileTime = false; + + // If set, will print out compiler performance benchmark results. + bool m_reportPerfBenchmark = false; String m_diagnosticOutput; diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 92f79eac5..1832a3b46 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -143,7 +143,7 @@ DIAGNOSTIC( 99, Error, unknownDebugOption, "unknown debug option, known optio DIAGNOSTIC( 100, Error, failedToLoadDownstreamCompiler, "failed to load downstream compiler '$0'") DIAGNOSTIC( 101, Error, downstreamCompilerDoesntSupportWholeProgramCompilation, "downstream compiler '$0' doesn't support whole program compilation") DIAGNOSTIC( 102, Note, downstreamCompileTime, "downstream compile time: $0s") - +DIAGNOSTIC( 103, Note, performanceBenchmarkResult, "compiler performance benchmark:\n$0") DIAGNOSTIC(99999, Note, noteFailedToLoadDynamicLibrary, "failed to load dynamic library '$0'") // diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 41230d169..d71cc5507 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -89,6 +89,7 @@ #include "../compiler-core/slang-artifact-associated-impl.h" #include "../core/slang-castable.h" +#include "../core/slang-performance-profiler.h" #include <assert.h> @@ -199,6 +200,7 @@ Result linkAndOptimizeIR( LinkingAndOptimizationOptions const& options, LinkedIR& outLinkedIR) { + SLANG_PROFILE; auto session = codeGenContext->getSession(); auto sink = codeGenContext->getSink(); auto target = codeGenContext->getTargetFormat(); diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp index 6d56736ad..2231e0ce7 100644 --- a/source/slang/slang-ir-autodiff.cpp +++ b/source/slang/slang-ir-autodiff.cpp @@ -6,6 +6,7 @@ #include "slang-ir-single-return.h" #include "slang-ir-ssa-simplification.h" #include "slang-ir-validate.h" +#include "../core/slang-performance-profiler.h" namespace Slang { @@ -1726,6 +1727,7 @@ bool processAutodiffCalls( DiagnosticSink* sink, IRAutodiffPassOptions const&) { + SLANG_PROFILE; bool modified = false; // Create shared context for all auto-diff related passes diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp index f825a9461..db4bb50a8 100644 --- a/source/slang/slang-ir-inline.cpp +++ b/source/slang/slang-ir-inline.cpp @@ -3,6 +3,7 @@ #include "slang-ir-ssa-simplification.h" +#include "../core/slang-performance-profiler.h" // This file provides general facilities for inlining function calls. // @@ -671,6 +672,8 @@ struct MandatoryEarlyInliningPass : InliningPassBase void performMandatoryEarlyInlining(IRModule* module) { + SLANG_PROFILE; + MandatoryEarlyInliningPass pass(module); pass.considerAllCallSites(); } @@ -785,6 +788,8 @@ struct ForceInliningPass : InliningPassBase void performForceInlining(IRModule* module) { + SLANG_PROFILE; + ForceInliningPass pass(module); pass.considerAllCallSites(); } diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index 162498bf0..a88d43db3 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -11,6 +11,7 @@ // that the concrete type of everything is known. #include "../compiler-core/slang-name.h" +#include "../core/slang-performance-profiler.h" #include "slang-ir.h" #include "slang-ir-clone.h" @@ -3843,6 +3844,8 @@ void legalizeResourceTypes( IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; + SLANG_UNUSED(sink); IRResourceTypeLegalizationContext context(module); @@ -3853,6 +3856,8 @@ void legalizeExistentialTypeLayout( IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; + SLANG_UNUSED(module); SLANG_UNUSED(sink); diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index f57919e44..081fd7486 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -9,6 +9,7 @@ #include "slang-ir-autodiff.h" #include "slang-module-library.h" +#include "../core/slang-performance-profiler.h" #include "../compiler-core/slang-artifact.h" namespace Slang @@ -1428,6 +1429,8 @@ static bool _isPublicOrHLSLExported(IRInst* inst) LinkedIR linkIR( CodeGenContext* codeGenContext) { + SLANG_PROFILE; + auto linkage = codeGenContext->getLinkage(); auto program = codeGenContext->getProgram(); auto session = codeGenContext->getSession(); diff --git a/source/slang/slang-ir-loop-unroll.cpp b/source/slang/slang-ir-loop-unroll.cpp index 05e829827..36a2abbfc 100644 --- a/source/slang/slang-ir-loop-unroll.cpp +++ b/source/slang/slang-ir-loop-unroll.cpp @@ -7,6 +7,7 @@ #include "slang-ir-util.h" #include "slang-ir-simplify-cfg.h" #include "slang-ir-dce.h" +#include "../core/slang-performance-profiler.h" namespace Slang { @@ -508,6 +509,8 @@ bool unrollLoopsInFunc( bool unrollLoopsInModule(IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; + for (auto inst : module->getGlobalInsts()) { if (auto genFunc = as<IRGeneric>(inst)) diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index fc810e54e..6a5abbf8c 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -15,7 +15,7 @@ #include "slang-ir-witness-table-wrapper.h" #include "slang-ir-ssa-simplification.h" #include "slang-ir-util.h" - +#include "../core/slang-performance-profiler.h" namespace Slang { @@ -181,6 +181,8 @@ namespace Slang IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; + SharedGenericsLoweringContext sharedContext; sharedContext.targetReq = targetReq; sharedContext.module = module; diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 80dcec82b..48b083b7d 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -7,6 +7,7 @@ #include "slang-ir-ssa-simplification.h" #include "slang-ir-lower-witness-lookup.h" #include "slang-ir-dce.h" +#include "../core/slang-performance-profiler.h" namespace Slang { @@ -2340,6 +2341,7 @@ bool specializeModule( IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; SpecializationContext context; context.module = module; context.sink = sink; diff --git a/source/slang/slang-ir-ssa-simplification.cpp b/source/slang/slang-ir-ssa-simplification.cpp index 66b4ceccb..43c9f8d2e 100644 --- a/source/slang/slang-ir-ssa-simplification.cpp +++ b/source/slang/slang-ir-ssa-simplification.cpp @@ -11,6 +11,7 @@ #include "slang-ir-remove-unused-generic-param.h" #include "slang-ir-redundancy-removal.h" #include "slang-ir-propagate-func-properties.h" +#include "../core/slang-performance-profiler.h" namespace Slang { @@ -18,6 +19,7 @@ namespace Slang // until no more changes are possible. void simplifyIR(IRModule* module, DiagnosticSink* sink) { + SLANG_PROFILE; bool changed = true; const int kMaxIterations = 8; const int kMaxFuncIterations = 16; diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 09c46b7ef..ad061a4e5 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -72,6 +72,7 @@ enum class OptionKind InputFilesRemain, EmitIr, ReportDownstreamTime, + ReportPerfBenchmark, SourceEmbedStyle, SourceEmbedName, @@ -427,6 +428,7 @@ void initCommandOptions(CommandOptions& options) { OptionKind::DumpWarningDiagnostics, "-dump-warning-diagnostics", nullptr, "Dump to output list of warning diagnostic numeric and name ids." }, { OptionKind::InputFilesRemain, "--", nullptr, "Treat the rest of the command line as input files."}, { OptionKind::ReportDownstreamTime, "-report-downstream-time", nullptr, "Reports the time spent in the downstream compiler." }, + { OptionKind::ReportPerfBenchmark, "-report-perf-benchmark", nullptr, "Reports compiler performance benchmark results." }, { OptionKind::SourceEmbedStyle, "-source-embed-style", "-source-embed-style <source-embed-style>", "If source embedding is enabled, defines the style used. When enabled (with any style other than `none`), " "will write compile results into embeddable source for the target language. " @@ -1867,6 +1869,11 @@ SlangResult OptionsParser::_parse( m_compileRequest->setReportDownstreamTime(true); break; } + case OptionKind::ReportPerfBenchmark: + { + m_compileRequest->setReportPerfBenchmark(true); + break; + } case OptionKind::ModuleName: { CommandLineArg moduleName; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index daa9cda3b..ffeabb0bd 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -7,7 +7,7 @@ #include "../core/slang-type-text-util.h" #include "../core/slang-type-convert-util.h" #include "../core/slang-castable.h" - +#include "../core/slang-performance-profiler.h" // Artifact #include "../compiler-core/slang-artifact-impl.h" #include "../compiler-core/slang-artifact-desc-util.h" @@ -4813,6 +4813,11 @@ void EndToEndCompileRequest::setReportDownstreamTime(bool value) m_reportDownstreamCompileTime = value; } +void EndToEndCompileRequest::setReportPerfBenchmark(bool value) +{ + m_reportPerfBenchmark = value; +} + void EndToEndCompileRequest::setDiagnosticCallback(SlangDiagnosticCallback callback, void const* userData) { ComPtr<ISlangWriter> writer(new CallbackWriter(callback, userData, WriterFlag::IsConsole)); @@ -5181,7 +5186,12 @@ SlangResult EndToEndCompileRequest::EndToEndCompileRequest::compile() double downstreamTime = downstreamEndTime - downstreamStartTime; String downstreamTimeStr = String(downstreamTime, "%.2f"); getSink()->diagnose(SourceLoc(), Diagnostics::downstreamCompileTime, downstreamTimeStr); - + } + if (m_reportPerfBenchmark) + { + StringBuilder perfResult; + PerformanceProfiler::getProfiler()->getResult(perfResult); + getSink()->diagnose(SourceLoc(), Diagnostics::performanceBenchmarkResult, perfResult.produceString()); } // Repro dump handling |
