Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a0975b8

Browse files
author
Daniel Podder
authored
Update PGO counts and port infrastructure fixes for Preview3 (#12260)
This PR is a roll-up of a handful of fixes made to the performance infrastructure and Linux PGO optimization support in master. The full list of changes follow: * Cherry-pick #12167, fixing an issue where the characters `'<'` and `'>'` broke Windows perf jobs when included in the PR title * Port #12201, revving the optdata package reference to the latest version and reflecting fixes made in the way we produce and package up counts on Linux * Cherry-pick #12238, so that we run perf tests against Linux binaries built the same way as official builds * Port #12239, fixing an issue where profile data was not being found on some Linux builds * Cherry-pick #12248, fixing a release build break on older toolsets (LLVM3.5) by disabling PGO and issuing a warning
1 parent 5f696b0 commit a0975b8

File tree

3 files changed

+164
-51
lines changed

3 files changed

+164
-51
lines changed

dir.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
<!-- Profile-based optimization data package versions -->
2525
<PropertyGroup>
26-
<PgoDataPackageVersion>2.0.0-release-20170531-3000</PgoDataPackageVersion>
26+
<PgoDataPackageVersion>2.0.0-release-20170612-1411</PgoDataPackageVersion>
2727
<!--<IbcDataPackageVersion></IbcDataPackageVersion>-->
2828
</PropertyGroup>
2929

perf.groovy

Lines changed: 147 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ def static getOSGroup(def os) {
8888
batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
8989
//Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
9090
//we have to do it all as one statement because cmd is called each time and we lose the set environment variable
91-
batchFile("if [%GIT_BRANCH:~0,7%] == [origin/] (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%) else (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%)\n" +
92-
"set BENCHVIEWNAME=${benchViewName}\n" +
93-
"set BENCHVIEWNAME=%BENCHVIEWNAME:\"=%\n" +
91+
batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
92+
"set \"BENCHVIEWNAME=${benchViewName}\"\n" +
93+
"set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=%\"\n" +
9494
"py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user \"dotnet-bot@microsoft.com\"\n" +
9595
"py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
9696
batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
@@ -198,9 +198,9 @@ def static getOSGroup(def os) {
198198
batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os} -Source https://dotnet.myget.org/F/dotnet-core -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
199199
//Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
200200
//we have to do it all as one statement because cmd is called each time and we lose the set environment variable
201-
batchFile("if [%GIT_BRANCH:~0,7%] == [origin/] (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%) else (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%)\n" +
202-
"set BENCHVIEWNAME=${benchViewName}\n" +
203-
"set BENCHVIEWNAME=%BENCHVIEWNAME:\"=%\n" +
201+
batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
202+
"set \"BENCHVIEWNAME=${benchViewName}\"\n" +
203+
"set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=%\"\n" +
204204
"py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"${benchViewName}\" --user \"dotnet-bot@microsoft.com\"\n" +
205205
"py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
206206
batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
@@ -234,10 +234,32 @@ def static getOSGroup(def os) {
234234
}
235235
}
236236

237+
def static getFullPerfJobName(def project, def os, def isPR) {
238+
return Utilities.getFullJobName(project, "perf_${os}", isPR)
239+
}
240+
237241
// Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
238242
[true, false].each { isPR ->
239-
['Ubuntu14.04'].each { os ->
240-
def newJob = job(Utilities.getFullJobName(project, "perf_${os}", isPR)) {
243+
def fullBuildJobName = Utilities.getFullJobName(project, 'perf_linux_build', isPR)
244+
def architecture = 'x64'
245+
def configuration = 'Release'
246+
247+
// Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
248+
['RHEL7.2'].each { os ->
249+
def newBuildJob = job(fullBuildJobName) {
250+
steps {
251+
shell("./build.sh verbose ${architecture} ${configuration}")
252+
}
253+
}
254+
Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
255+
Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
256+
Utilities.addArchival(newBuildJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
257+
}
258+
259+
// Actual perf testing on the following OSes
260+
def perfOSList = ['Ubuntu14.04']
261+
perfOSList.each { os ->
262+
def newJob = job(getFullPerfJobName(project, os, isPR)) {
241263

242264
label('linux_clr_perf')
243265
wrappers {
@@ -254,22 +276,26 @@ def static getOSGroup(def os) {
254276
}
255277
}
256278

257-
// Cap the maximum number of iterations to 21.
258279
parameters {
280+
// Cap the maximum number of iterations to 21.
259281
stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '21', 'Sets the number of iterations to twenty one. We are doing this to limit the amount of data that we upload as 20 iterations is enought to get a good sample')
260282
stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '21', 'Sets the number of iterations to twenty one. We are doing this to limit the amount of data that we upload as 20 iterations is enought to get a good sample')
283+
stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
261284
}
262285

263286
def osGroup = getOSGroup(os)
264-
def architecture = 'x64'
265-
def configuration = 'Release'
266287
def runType = isPR ? 'private' : 'rolling'
267288
def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
268289

269290
steps {
270291
shell("./tests/scripts/perf-prep.sh")
271292
shell("./init-tools.sh")
272-
shell("./build.sh ${architecture} ${configuration}")
293+
copyArtifacts(fullBuildJobName) {
294+
includePatterns("bin/**")
295+
buildSelector {
296+
buildNumber('\${PRODUCT_BUILD}')
297+
}
298+
}
273299
shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
274300
"python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user \"dotnet-bot@microsoft.com\"\n" +
275301
"python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
@@ -306,26 +332,73 @@ def static getOSGroup(def os) {
306332
numToKeep(1000)
307333
}
308334
}
335+
} // os
336+
337+
def flowJobPerfRunList = perfOSList.collect { os ->
338+
"{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullPerfJobName(project, os, isPR)}') }"
339+
}
340+
def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_linux_flow", isPR, '')) {
309341
if (isPR) {
310-
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
311-
builder.setGithubContext("${os} Perf Tests")
312-
builder.triggerOnlyOnComment()
313-
builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+perf.*")
314-
builder.triggerForBranch(branch)
315-
builder.emitTrigger(newJob)
316-
}
317-
else {
318-
// Set a push trigger
319-
TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
320-
builder.emitTrigger(newJob)
342+
parameters {
343+
stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview. The final name will be of the form <branch> private BenchviewCommitName')
344+
}
321345
}
322-
} // os
346+
buildFlow("""
347+
// First, build the bits on RHEL7.2
348+
b = build(params, '${fullBuildJobName}')
349+
350+
// Then, run the perf tests
351+
parallel(
352+
${flowJobPerfRunList.join(",\n ")}
353+
)
354+
""")
355+
}
356+
357+
Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
358+
Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
359+
360+
if (isPR) {
361+
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
362+
builder.setGithubContext("Linux Perf Test Flow")
363+
builder.triggerOnlyOnComment()
364+
builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+perf\\W+flow.*")
365+
builder.triggerForBranch(branch)
366+
builder.emitTrigger(newFlowJob)
367+
}
368+
else {
369+
// Set a push trigger
370+
TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
371+
builder.emitTrigger(newFlowJob)
372+
}
373+
323374
} // isPR
324375

376+
def static getFullThroughputJobName(def project, def os, def isPR) {
377+
return Utilities.getFullJobName(project, "perf_throughput_${os}", isPR)
378+
}
379+
325380
// Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
326381
[true, false].each { isPR ->
327-
['Ubuntu14.04'].each { os ->
328-
def newJob = job(Utilities.getFullJobName(project, "perf_throughput_${os}", isPR)) {
382+
def fullBuildJobName = Utilities.getFullJobName(project, 'perf_throughput_linux_build', isPR)
383+
def architecture = 'x64'
384+
def configuration = 'Release'
385+
386+
// Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
387+
['RHEL7.2'].each { os ->
388+
def newBuildJob = job(fullBuildJobName) {
389+
steps {
390+
shell("./build.sh verbose ${architecture} ${configuration}")
391+
}
392+
}
393+
Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
394+
Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
395+
Utilities.addArchival(newBuildJob, "bin/Product/**")
396+
}
397+
398+
// Actual perf testing on the following OSes
399+
def throughputOSList = ['Ubuntu14.04']
400+
throughputOSList.each { os ->
401+
def newJob = job(getFullThroughputJobName(project, os, isPR)) {
329402

330403
label('linux_clr_perf')
331404
wrappers {
@@ -341,16 +414,24 @@ def static getOSGroup(def os) {
341414
stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview. The final name will be of the form <branch> private BenchviewCommitName')
342415
}
343416
}
417+
418+
parameters {
419+
stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
420+
}
421+
344422
def osGroup = getOSGroup(os)
345-
def architecture = 'x64'
346-
def configuration = 'Release'
347423
def runType = isPR ? 'private' : 'rolling'
348424
def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
349425

350426
steps {
351427
shell("bash ./tests/scripts/perf-prep.sh --throughput")
352428
shell("./init-tools.sh")
353-
shell("./build.sh ${architecture} ${configuration}")
429+
copyArtifacts(fullBuildJobName) {
430+
includePatterns("bin/Product/**")
431+
buildSelector {
432+
buildNumber('\${PRODUCT_BUILD}')
433+
}
434+
}
354435
shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
355436
"python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user \"dotnet-bot@microsoft.com\"\n" +
356437
"python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
@@ -383,18 +464,43 @@ def static getOSGroup(def os) {
383464
numToKeep(1000)
384465
}
385466
}
467+
} // os
468+
469+
def flowJobTPRunList = throughputOSList.collect { os ->
470+
"{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullThroughputJobName(project, os, isPR)}') }"
471+
}
472+
def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_throughput_linux_flow", isPR, '')) {
386473
if (isPR) {
387-
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
388-
builder.setGithubContext("${os} Throughput Perf Tests")
389-
builder.triggerOnlyOnComment()
390-
builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+throughput.*")
391-
builder.triggerForBranch(branch)
392-
builder.emitTrigger(newJob)
393-
}
394-
else {
395-
// Set a push trigger
396-
TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
397-
builder.emitTrigger(newJob)
474+
parameters {
475+
stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview. The final name will be of the form <branch> private BenchviewCommitName')
476+
}
398477
}
399-
} // os
478+
buildFlow("""
479+
// First, build the bits on RHEL7.2
480+
b = build(params, '${fullBuildJobName}')
481+
482+
// Then, run the perf tests
483+
parallel(
484+
${flowJobTPRunList.join(",\n ")}
485+
)
486+
""")
487+
}
488+
489+
Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
490+
Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
491+
492+
if (isPR) {
493+
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
494+
builder.setGithubContext("Linux Throughput Perf Test Flow")
495+
builder.triggerOnlyOnComment()
496+
builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+throughput\\W+flow.*")
497+
builder.triggerForBranch(branch)
498+
builder.emitTrigger(newFlowJob)
499+
}
500+
else {
501+
// Set a push trigger
502+
TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
503+
builder.emitTrigger(newFlowJob)
504+
}
505+
400506
} // isPR

pgosupport.cmake

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@ function(add_pgo TargetName)
1111
if(WIN32)
1212
set(ProfileFileName "${TargetName}.pgd")
1313
else(WIN32)
14-
# Clang/LLVM uses one profdata file for the entire repo
15-
set(ProfileFileName "coreclr.profdata")
14+
set(ProfileFileName "${TargetName}.profdata")
1615
endif(WIN32)
1716

1817
set(CLR_CMAKE_OPTDATA_PACKAGEWITHRID "optimization.${CLR_CMAKE_TARGET_OS}-${CLR_CMAKE_TARGET_ARCH}.PGO.CoreCLR")
18+
19+
# On case-sensitive file systems, NuGet packages are restored to lowercase paths
20+
string(TOLOWER "${CLR_CMAKE_OPTDATA_PACKAGEWITHRID}/${CLR_CMAKE_OPTDATA_VERSION}" OptDataVersionedSubPath)
21+
1922
file(TO_NATIVE_PATH
20-
"${CLR_CMAKE_PACKAGES_DIR}/${CLR_CMAKE_OPTDATA_PACKAGEWITHRID}/${CLR_CMAKE_OPTDATA_VERSION}/data/${ProfileFileName}"
23+
"${CLR_CMAKE_PACKAGES_DIR}/${OptDataVersionedSubPath}/data/${ProfileFileName}"
2124
ProfilePath
2225
)
23-
# NuGet packages are restored to lowercase paths
24-
string(TOLOWER "${ProfilePath}" ProfilePath)
2526

2627
if(CLR_CMAKE_PGO_INSTRUMENT)
2728
if(WIN32)
@@ -41,10 +42,16 @@ function(add_pgo TargetName)
4142
set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /LTCG /USEPROFILE:PGD=${ProfilePath}")
4243
else(WIN32)
4344
if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
44-
if(HAVE_LTO)
45-
target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-use=${ProfilePath} -Wno-profile-instr-out-of-date)
46-
set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fuse-ld=gold -fprofile-instr-use=${ProfilePath}")
47-
endif(HAVE_LTO)
45+
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
46+
if(HAVE_LTO)
47+
target_compile_options(${TargetName} PRIVATE -flto -fprofile-instr-use=${ProfilePath} -Wno-profile-instr-out-of-date)
48+
set_property(TARGET ${TargetName} APPEND_STRING PROPERTY LINK_FLAGS " -flto -fuse-ld=gold -fprofile-instr-use=${ProfilePath}")
49+
else(HAVE_LTO)
50+
message(WARNING "LTO is not supported, skipping profile guided optimizations")
51+
endif(HAVE_LTO)
52+
else(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
53+
message(WARNING "PGO is not supported; Clang 3.6 or later is required for profile guided optimizations")
54+
endif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
4855
endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELWITHDEBINFO)
4956
endif(WIN32)
5057
endif(EXISTS ${ProfilePath})

0 commit comments

Comments
 (0)