* Add support for mono AOT pass

* Add documentation for using mono aot args
This commit is contained in:
Alexander Kyte 2019-01-17 13:43:58 -05:00 коммит произвёл Adam Sitnik
Родитель 8d971412a8
Коммит 573566b70f
7 изменённых файлов: 129 добавлений и 5 удалений

Просмотреть файл

@ -9,6 +9,9 @@ If you apply `[MonoJob]` attribute to your class we use your default mono runtim
If you want to compare different versions of Mono you need to provide use the custom paths.
You can do this today by using the overloaded ctor of MonoJob attribute or by specifying the runtime in a fluent way.
The mono runtime can also operate as an ahead-of-time compiler. Using mono's AOT mode requires providing the AOT compilation
arguments, as well as the path to mono's corlib. (See IntroCustomMonoObjectStyleAot in the below example).
### Source code
[!code-csharp[IntroCustomMono.cs](../../../samples/BenchmarkDotNet.Samples/IntroCustomMono.cs)]

Просмотреть файл

@ -3,6 +3,7 @@ using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using System;
namespace BenchmarkDotNet.Samples
{
@ -42,6 +43,36 @@ namespace BenchmarkDotNet.Samples
}
}
// ** Object Style, Using AOT **
[Config(typeof(Config))]
public class IntroCustomMonoObjectStyleAot
{
private class Config : ManualConfig
{
public void AddMono (string name, string mono_top_dir)
{
var aot_compile_args = "--aot=llvm";
var mono_bcl = String.Format(@"{0}\lib\mono\4.5", mono_top_dir);
var mono_bin = String.Format(@"{0}\bin\mono", mono_top_dir);
Add(Job.ShortRun.With(new MonoRuntime(
name, mono_bin, aot_compile_args, mono_bcl)));
}
public Config()
{
AddMono("Mono x64", @"C:\Program Files\Mono");
AddMono("Mono x86", @"C:\Program Files (x86)");
}
}
[Benchmark]
public void Foo()
{
// Benchmark body
}
}
// *** Fluent Config ***
public class IntroCustomMonoFluentConfig

Просмотреть файл

@ -78,16 +78,28 @@ namespace BenchmarkDotNet.Environments
{
public string CustomPath { get; }
public string AotArgs { get; }
public string MonoBclPath { get; }
public MonoRuntime() : base("Mono")
{
}
public MonoRuntime(string name, string customPath) : base(name) => CustomPath = customPath;
public MonoRuntime(string name, string customPath, string aotArgs, string monoBclPath) : base(name)
{
CustomPath = customPath;
AotArgs = aotArgs;
MonoBclPath = monoBclPath;
}
public override bool Equals(object obj) => obj is MonoRuntime other && Equals(other);
public bool Equals(MonoRuntime other) => other != null && Name == other.Name && CustomPath == other.CustomPath;
public bool Equals(MonoRuntime other) => other != null && Name == other.Name && CustomPath == other.CustomPath && AotArgs == other.AotArgs && MonoBclPath == other.MonoBclPath;
public override int GetHashCode() => Name.GetHashCode() ^ (CustomPath?.GetHashCode() ?? 0);
int GetHashCodeComposite() => String.Format("{0}{1}{2}", CustomPath?.GetHashCode(), AotArgs?.GetHashCode(), MonoBclPath?.GetHashCode()).GetHashCode ();
public override int GetHashCode() => Name.GetHashCode() ^ GetHashCodeComposite ();
}
}
}

Просмотреть файл

@ -118,6 +118,8 @@ namespace BenchmarkDotNet.Toolchains
case MonoRuntime mono:
start.FileName = mono.CustomPath ?? "mono";
start.Arguments = GetMonoArguments(benchmarkCase.Job, exePath, args, resolver);
if (mono.MonoBclPath != null)
start.EnvironmentVariables["MONO_PATH"] = mono.MonoBclPath;
break;
default:
throw new NotSupportedException("Runtime = " + runtime);

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -11,9 +12,74 @@ using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using OurPlatform = BenchmarkDotNet.Environments.Platform;
using MonoRuntime = BenchmarkDotNet.Environments.MonoRuntime;
namespace BenchmarkDotNet.Toolchains.Roslyn
{
[PublicAPI]
public class MonoAotBuilder : Builder
{
MonoRuntime mono;
public MonoAotBuilder (MonoRuntime monoReference) => mono = monoReference;
[PublicAPI]
public override BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)
{
BuildResult result = base.Build(generateResult, buildPartition, logger);
if (!result.IsBuildSuccess)
return result;
var dllPath = generateResult.ArtifactsPaths.ExecutablePath;
var monoPath = mono.CustomPath ?? "mono";
try
{
using (var process = new Process { StartInfo = CreateMonoAot(monoPath, dllPath) })
{
logger.WriteLineInfo("// Execute: " + process.StartInfo.FileName + " " + process.StartInfo.Arguments);
ConsoleExitHandler.Instance.Process = process;
process.Start();
process.WaitForExit(); // should we add timeout here?
if (process.ExitCode != 0) {
string failure = String.Format("Attempt to AOT failed: {0} {1} with exit code: {2}", process.StartInfo.FileName, process.StartInfo.Arguments, process.ExitCode);
logger.WriteLineError(failure);
return BuildResult.Failure(generateResult, failure);
}
}
}
finally
{
ConsoleExitHandler.Instance.Process = null;
}
return result;
}
private ProcessStartInfo CreateMonoAot(string monoPath, string filePath)
{
var absFilePath = Path.GetFullPath(filePath);
var start = new ProcessStartInfo
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(absFilePath)
};
start.FileName = monoPath;
start.Arguments = String.Format("{0} {1}", mono.AotArgs, absFilePath);
if (mono.MonoBclPath != null)
start.EnvironmentVariables["MONO_PATH"] = mono.MonoBclPath;
return start;
}
}
[PublicAPI]
public class Builder : IBuilder
{
@ -22,7 +88,7 @@ namespace BenchmarkDotNet.Toolchains.Roslyn
private static readonly Lazy<AssemblyMetadata[]> FrameworkAssembliesMetadata = new Lazy<AssemblyMetadata[]>(GetFrameworkAssembliesMetadata);
[PublicAPI]
public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)
public virtual BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)
{
logger.WriteLineInfo($"BuildScript: {generateResult.ArtifactsPaths.BuildScriptFilePath}");

Просмотреть файл

@ -2,6 +2,7 @@
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Environments;
using JetBrains.Annotations;
namespace BenchmarkDotNet.Toolchains.Roslyn
@ -14,6 +15,11 @@ namespace BenchmarkDotNet.Toolchains.Roslyn
{
public static IToolchain Instance = new RoslynToolchain();
[PublicAPI]
public RoslynToolchain(MonoRuntime mono) : base("MonoAot", new Generator(), new MonoAotBuilder(mono), new Executor())
{
}
[PublicAPI]
public RoslynToolchain() : base("Roslyn", new Generator(), new Builder(), new Executor())
{

Просмотреть файл

@ -20,10 +20,14 @@ namespace BenchmarkDotNet.Toolchains
switch (runtime)
{
case ClrRuntime _:
case MonoRuntime _:
if(RuntimeInformation.IsNetCore)
return CsProjClassicNetToolchain.Current.Value;
return RoslynToolchain.Instance;
case MonoRuntime mono:
if(mono.AotArgs != null)
return new RoslynToolchain (mono);
return RoslynToolchain.Instance;
case CoreRuntime _:
return CsProjCoreToolchain.Current.Value;