Skip to content

Commit

Permalink
[Perf] Add ThreadPool options, print more environment info (#20372)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeharder authored Apr 16, 2021
1 parent 289d8e7 commit 835bf84
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
12 changes: 12 additions & 0 deletions common/Perf/Azure.Test.Perf/PerfOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ public class PerfOptions
[Option('l', "latency", HelpText = "Track and print per-operation latency statistics")]
public bool Latency { get; set; }

[Option("max-io-completion-threads", HelpText = "The maximum number of asynchronous I/O threads that the thread pool creates on demand")]
public int? MaxIOCompletionThreads { get; set; }

[Option("max-worker-threads", HelpText = "The maximum number of worker threads that the thread pool creates on demand")]
public int? MaxWorkerThreads { get; set; }

[Option("min-io-completion-threads", HelpText = "The minimum number of asynchronous I/O threads that the thread pool creates on demand")]
public int? MinIOCompletionThreads { get; set; }

[Option("min-worker-threads", HelpText = "The minimum number of worker threads that the thread pool creates on demand")]
public int? MinWorkerThreads { get; set; }

[Option("no-cleanup", HelpText = "Disables test cleanup")]
public bool NoCleanup { get; set; }

Expand Down
61 changes: 56 additions & 5 deletions common/Perf/Azure.Test.Perf/PerfProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ private static async Task Run(Type testType, PerfOptions options)
}));
Console.WriteLine();

ConfigureThreadPool(options);

PrintEnvironment();

using var setupStatusCts = new CancellationTokenSource();
var setupStatusThread = PerfStressUtilities.PrintStatus("=== Setup ===", () => ".", newLine: false, setupStatusCts.Token);

Expand Down Expand Up @@ -174,6 +178,52 @@ private static async Task Run(Type testType, PerfOptions options)
PrintAssemblyVersions(testType);
}

private static void ConfigureThreadPool(PerfOptions options)
{
if (options.MinWorkerThreads.HasValue || options.MinIOCompletionThreads.HasValue)
{
ThreadPool.GetMinThreads(out var minWorkerThreads, out var minIOCompletionThreads);
var successful = ThreadPool.SetMinThreads(options.MinWorkerThreads ?? minWorkerThreads,
options.MinIOCompletionThreads ?? minIOCompletionThreads);

if (!successful)
{
throw new InvalidOperationException("ThreadPool.SetMinThreads() was unsuccessful");
}
}

if (options.MaxWorkerThreads.HasValue || options.MaxIOCompletionThreads.HasValue)
{
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxIOCompletionThreads);
var successful = ThreadPool.SetMaxThreads(options.MaxWorkerThreads ?? maxWorkerThreads,
options.MaxIOCompletionThreads ?? maxIOCompletionThreads);

if (!successful)
{
throw new InvalidOperationException("ThreadPool.SetMaxThreads() was unsuccessful");
}
}
}

private static void PrintEnvironment()
{
Console.WriteLine("=== Environment ===");

Console.WriteLine($"GCSettings.IsServerGC: {GCSettings.IsServerGC}");

Console.WriteLine($"Environment.ProcessorCount: {Environment.ProcessorCount}");
Console.WriteLine($"Environment.Is64BitProcess: {Environment.Is64BitProcess}");

ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads);
ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);
Console.WriteLine($"ThreadPool.MinWorkerThreads: {minWorkerThreads}");
Console.WriteLine($"ThreadPool.MinCompletionPortThreads: {minCompletionPortThreads}");
Console.WriteLine($"ThreadPool.MaxWorkerThreads: {maxWorkerThreads}");
Console.WriteLine($"ThreadPool.MaxCompletionPortThreads: {maxCompletionPortThreads}");

Console.WriteLine();
}

private static void PrintAssemblyVersions(Type testType)
{
Console.WriteLine("=== Versions ===");
Expand All @@ -186,10 +236,6 @@ private static void PrintAssemblyVersions(Type testType)
// Include all Track1 and Track2 assemblies
.Where(a => a.GetName().Name.StartsWith("Azure", StringComparison.OrdinalIgnoreCase) ||
a.GetName().Name.StartsWith("Microsoft.Azure", StringComparison.OrdinalIgnoreCase))
// Exclude this perf framework
.Where(a => a != Assembly.GetExecutingAssembly())
// Exclude assembly containing the perf test itself
.Where(a => a != testType.Assembly)
// Exclude Azure.Core.TestFramework since it is only used to setup environment and should not impact results
.Where(a => !a.GetName().Name.Equals("Azure.Core.TestFramework", StringComparison.OrdinalIgnoreCase))
.OrderBy(a => a.GetName().Name);
Expand All @@ -200,11 +246,16 @@ private static void PrintAssemblyVersions(Type testType)
var referencedVersion = referencedAssemblies.Where(r => r.Name == name).SingleOrDefault()?.Version;
var loadedVersion = a.GetName().Version;
var informationalVersion = FileVersionInfo.GetVersionInfo(a.Location).ProductVersion;
var debuggableAttribute = (DebuggableAttribute)(a.GetCustomAttribute(typeof(DebuggableAttribute)));

Console.WriteLine($"{name}:");
Console.WriteLine($" Referenced: {referencedVersion}");
if (referencedVersion != null)
{
Console.WriteLine($" Referenced: {referencedVersion}");
}
Console.WriteLine($" Loaded: {loadedVersion}");
Console.WriteLine($" Informational: {informationalVersion}");
Console.WriteLine($" JITOptimizer: {(debuggableAttribute.IsJITOptimizerDisabled ? "Disabled" : "Enabled")}");
}

Console.WriteLine();
Expand Down

0 comments on commit 835bf84

Please sign in to comment.