Skip to content

Commit 77674cf

Browse files
committed
dotnet dynamic pgo
1 parent d7beca5 commit 77674cf

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

bench/algorithm/nbody/1.ml

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,21 @@ type planet = { mutable x : float; mutable y : float; mutable z : float;
1616
let advance bodies dt =
1717
let n = Array.length bodies - 1 in
1818
for i = 0 to Array.length bodies - 1 do
19-
let b = bodies.(i) in
19+
let b1 = bodies.(i) in
2020
for j = i+1 to Array.length bodies - 1 do
21-
let b' = bodies.(j) in
22-
let dx = b.x -. b'.x and dy = b.y -. b'.y and dz = b.z -. b'.z in
21+
let b2 = bodies.(j) in
22+
let dx = b1.x -. b2.x and dy = b1.y -. b2.y and dz = b1.z -. b2.z in
2323
let dist2 = dx *. dx +. dy *. dy +. dz *. dz in
2424
let mag = dt /. (dist2 *. sqrt(dist2)) in
25-
26-
b.vx <- b.vx -. dx *. b'.mass *. mag;
27-
b.vy <- b.vy -. dy *. b'.mass *. mag;
28-
b.vz <- b.vz -. dz *. b'.mass *. mag;
29-
30-
b'.vx <- b'.vx +. dx *. b.mass *. mag;
31-
b'.vy <- b'.vy +. dy *. b.mass *. mag;
32-
b'.vz <- b'.vz +. dz *. b.mass *. mag;
25+
let b2_m_mul_mag = b2.mass *. mag in
26+
b1.vx <- b1.vx -. dx *. b2_m_mul_mag;
27+
b1.vy <- b1.vy -. dy *. b2_m_mul_mag;
28+
b1.vz <- b1.vz -. dz *. b2_m_mul_mag;
29+
30+
let b1_m_mul_mag = b1.mass *. mag in
31+
b2.vx <- b2.vx +. dx *. b1_m_mul_mag;
32+
b2.vy <- b2.vy +. dy *. b1_m_mul_mag;
33+
b2.vz <- b2.vz +. dz *. b1_m_mul_mag;
3334
done
3435
done;
3536
for i = 0 to n do

bench/bench_csharp.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,17 @@ environments:
6060
build: dotnet publish -c Release -r linux-x64 -f net6 --self-contained true -p:PublishSingleFile=true -o out # -p:PublishReadyToRun=true
6161
out_dir: out
6262
run_cmd: app
63+
- os: linux
64+
compiler: dotnet/dynpgo
65+
version: 6
66+
compiler_version_command: dotnet --version
67+
docker: mcr.microsoft.com/dotnet/sdk:6.0
68+
docker_volumns:
69+
- /tmp/.nuget/packages:/root/.nuget/packages/
70+
include: dotnet
71+
build: dotnet publish -c Release -r linux-x64 -f net6 --self-contained true -p:PublishSingleFile=true -o out # -p:PublishReadyToRun=true
72+
out_dir: out
73+
run_cmd: app
74+
run_cmd_env:
75+
# https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/
76+
DOTNET_TieredPGO: 1

bench/tool/CpuInfo.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,27 @@ public class CpuInfo
1212

1313
public string RawText { get; private set; }
1414

15+
public int NumOfCores { get; private set; }
16+
17+
public string Architecture { get; private set; }
18+
1519
public override string ToString()
1620
{
17-
return $"Cpu: {ModelName} (Model {Model})";
21+
return $"[{Architecture}][{NumOfCores} cores] {ModelName}";
1822
}
1923

2024
public static bool TryParse(string rawText, out CpuInfo cpuInfo)
2125
{
22-
Match match = Regex.Match(rawText, @"^Model:\s*(?<model>\d+)\s*$\s*^Model name:\s*(?<name>.+?)$", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase);
26+
Match match = Regex.Match(rawText, @"^Architecture:(?<arch>.+?)\s*$[^.$]*?^CPU\(s\):\s*(?<core>\d+)\s*$[^.$]*?^Model:\s*(?<model>\d+)\s*$\s*^Model name:\s*(?<name>.+?)$", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase);
2327
if (match.Success)
2428
{
2529
cpuInfo = new CpuInfo
2630
{
2731
ModelName = match.Groups["name"].Value.Trim(),
2832
Model = int.Parse(match.Groups["model"].Value),
2933
RawText = rawText,
34+
NumOfCores = int.Parse(match.Groups["core"].Value),
35+
Architecture = match.Groups["arch"].Value.Trim(),
3036
};
3137
return true;
3238
}

bench/tool/ProcessUtils.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public static async Task<ProcessMeasurement> MeasureAsync(
151151
int sampleIntervalMS = 3,
152152
bool forceCheckChildProcesses = false,
153153
double timeoutSeconds = 0.0,
154+
IDictionary<string, string> env = null,
154155
CancellationToken token = default)
155156
{
156157
using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(token);
@@ -311,7 +312,7 @@ public static async Task<ProcessMeasurement> MeasureAsync(
311312
asyncRead: true,
312313
stdOutBuilder: null,
313314
stdErrorBuilder: null,
314-
env: null,
315+
env: env,
315316
cts.Token,
316317
onStart: () => manualResetEvent.Set()).ConfigureAwait(false);
317318
sw.Stop();
@@ -469,6 +470,7 @@ public static async Task<int> RunProcessAsync(
469470
using (p)
470471
{
471472
bool useShellExecute = p.StartInfo.UseShellExecute;
473+
p.StartInfo.RedirectStandardInput = !useShellExecute;
472474
p.StartInfo.RedirectStandardOutput = !useShellExecute;
473475
p.StartInfo.RedirectStandardError = !useShellExecute;
474476
if (env?.Count > 0)

bench/tool/Program.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ static Program()
2828
private const string TaskTest = "test";
2929
private const string TaskBench = "bench";
3030

31-
private static bool _verbose = false;
31+
private static bool s_verbose = false;
32+
private static CpuInfo s_cpuInfo;
3233

3334
/// <summary>
3435
/// Main function
@@ -65,8 +66,10 @@ public static async Task Main(
6566
string[] problems = null,
6667
string[] environments = null)
6768
{
69+
s_cpuInfo = await CpuInfo.LsCpuAsync().ConfigureAwait(false);
70+
6871
Stopwatch timer = Stopwatch.StartNew();
69-
_verbose = verbose;
72+
s_verbose = verbose;
7073
config.EnsureFileExists();
7174
algorithm.EnsureDirectoryExists();
7275
include.EnsureDirectoryExists();
@@ -101,11 +104,10 @@ public static async Task Main(
101104
HashSet<string> includedOsEnvironments = new HashSet<string>(environments ?? new string[] { }, StringComparer.OrdinalIgnoreCase);
102105
HashSet<string> includedProblems = new HashSet<string>(problems ?? new string[] { }, StringComparer.OrdinalIgnoreCase);
103106

104-
CpuInfo cpuInfo = await CpuInfo.LsCpuAsync().ConfigureAwait(false);
105-
if (cpuInfo != null)
107+
if (s_cpuInfo != null)
106108
{
107-
Logger.Info(cpuInfo.ToString());
108-
if (GithubActionUtils.IsGithubBuild && task == TaskBench && cpuInfo.Model < 79)
109+
Logger.Info($"CPU: {s_cpuInfo}");
110+
if (GithubActionUtils.IsGithubBuild && task == TaskBench && s_cpuInfo.Model < 79)
109111
{
110112
// To print cpu features, use
111113
// either: 'rustc +nightly --print=cfg -C target-cpu=broadwell' (features like avx512 are missing from stable)
@@ -119,6 +121,10 @@ public static async Task Main(
119121
HashSet<string> SetupDockerProvidedRuntimeDedupContext = new HashSet<string>();
120122
foreach (YamlLangConfig c in langConfigs.OrderBy(i => i.Lang))
121123
{
124+
if (!c.Enabled)
125+
{
126+
continue;
127+
}
122128
if (includedLanguages.Count > 0
123129
&& !includedLanguages.Contains(c.Lang))
124130
{
@@ -130,7 +136,11 @@ public static async Task Main(
130136

131137
foreach (YamlLangEnvironmentConfig env in c.Environments ?? Enumerable.Empty<YamlLangEnvironmentConfig>())
132138
{
133-
if (includedOsEnvironments.Count > 0
139+
if (!env.Enabled)
140+
{
141+
continue;
142+
}
143+
if (includedOsEnvironments.Count > 0
134144
&& !includedOsEnvironments.Contains(env.Os))
135145
{
136146
continue;
@@ -294,7 +304,7 @@ private static async Task BuildAsync(
294304
Logger.Debug($"Copying {srcCodePath} to {srcCodeDestPath}");
295305
//File.Copy(srcCodePath, srcCodeDestPath, overwrite: true);
296306
await File.WriteAllTextAsync(path: srcCodeDestPath, await File.ReadAllTextAsync(srcCodePath).ConfigureAwait(false)).ConfigureAwait(false);
297-
if (_verbose)
307+
if (s_verbose)
298308
{
299309
await ProcessUtils.RunCommandAsync($"ls -al \"{tmpDir.FullPath}\"", asyncRead: false).ConfigureAwait(false);
300310
}
@@ -445,7 +455,7 @@ await ProcessUtils.RunCommandsAsync(
445455

446456
await buildOutputJson.SaveAsync(buildOutput).ConfigureAwait(false);
447457

448-
if (_verbose)
458+
if (s_verbose)
449459
{
450460
await ProcessUtils.RunCommandAsync($"ls -al {buildOutput}", asyncRead: false).ConfigureAwait(false);
451461
}
@@ -521,7 +531,7 @@ await ProcessUtils.RunCommandAsync(
521531
asyncRead: false,
522532
out string stdOut,
523533
out string stdErr,
524-
env: null,
534+
env: langEnvConfig.RunCmdEnv,
525535
default);
526536
if (StringComparer.Ordinal.Equals(expectedOutput.TrimEnd(), stdOut.TrimEnd()))
527537
{
@@ -631,7 +641,12 @@ private static async Task BenchAsync(
631641
{
632642
try
633643
{
634-
ProcessMeasurement measurement = await ProcessUtils.MeasureAsync(runPsi, forceCheckChildProcesses: langEnvConfig.ForceCheckChildProcesses, timeoutSeconds: test.TimeoutSeconds).ConfigureAwait(false);
644+
ProcessMeasurement measurement = await ProcessUtils.MeasureAsync(
645+
runPsi,
646+
forceCheckChildProcesses: langEnvConfig.ForceCheckChildProcesses,
647+
timeoutSeconds: test.TimeoutSeconds,
648+
env: langEnvConfig.RunCmdEnv).ConfigureAwait(false);
649+
635650
if (measurement != null && measurement.Elapsed.TotalMilliseconds > 0)
636651
{
637652
Logger.Debug($"({buildId}){langConfig.Lang}:{problem.Name}:{test.Input} {measurement}");
@@ -679,6 +694,7 @@ private static async Task BenchAsync(
679694
string benchResultJsonPath = Path.Combine(benchResultDir, $"{buildId}_{test.Input}.json");
680695
await File.WriteAllTextAsync(benchResultJsonPath, JsonConvert.SerializeObject(new
681696
{
697+
cpuInfo = s_cpuInfo?.ToString(),
682698
lang = langConfig.Lang,
683699
os = langEnvConfig.Os,
684700
compiler = langEnvConfig.Compiler,

bench/tool/YamlLangConfig.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public abstract class LangConfigBase
5353
public string RuntimeVersionRegex { get; set; }
5454

5555
public string SourceRenameTo { get; set; }
56+
57+
public bool Enabled { get; set; } = true;
5658
}
5759

5860
public class YamlLangConfig : LangConfigBase
@@ -109,6 +111,8 @@ public class YamlLangEnvironmentConfig : LangConfigBase
109111

110112
public string RunCmd { get; set; }
111113

114+
public Dictionary<string, string> RunCmdEnv { get; set; }
115+
112116
public bool RuntimeIncluded { get; set; } = true;
113117

114118
public bool ForceCheckChildProcesses { get; set; } = false;

0 commit comments

Comments
 (0)