Skip to content

Commit 3a75302

Browse files
committed
[GR-52170] Document -O, -march, and build artifacts.
PullRequest: graal/17010
2 parents f269c9d + 9802d57 commit 3a75302

File tree

9 files changed

+66
-22
lines changed

9 files changed

+66
-22
lines changed

docs/reference-manual/native-image/BuildOutput.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Recommendations:
6666
--------------------------------------------------------------------------------
6767
0.8s (4.6% of total time) in 35 GCs | Peak RSS: 1.93GB | CPU load: 9.61
6868
--------------------------------------------------------------------------------
69-
Produced artifacts:
69+
Build artifacts:
7070
/home/janedoe/helloworld/helloworld (executable)
7171
/home/janedoe/helloworld/helloworld.debug (debug_info)
7272
/home/janedoe/helloworld/sources (debug_info)
@@ -341,11 +341,22 @@ If there is enough headroom and the [GC statistics](#glossary-garbage-collection
341341
The CPU time used by the process divided by the total process time.
342342
Increase the number of CPU cores to reduce the time to build the native binary.
343343
344+
## <a name="glossary-build-artifacts"></a>Build Artifacts
345+
346+
The list of all build artifacts.
347+
This includes the generated native binary, but it can also contain other artifacts such as additional libraries, C header files, or debug info.
348+
Some of these artifacts must remain in the same location with the native binary as they are needed at run time.
349+
For applications using AWT, for example, the build process will also output libraries from the JDK and shims to provide compatible AWT support.
350+
These libraries need to be copied and distributed together with the native binary.
351+
Use the `-H:+GenerateBuildArtifactsFile` option to instruct the builder to produce a machine-readable version of the build artifact list in JSON format.
352+
Such a JSON file validates against the JSON schema defined in [`build-artifacts-schema-v0.9.0.json`](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json).
353+
This schema also contains descriptions for each possible artifact type and explains whether they are needed at run time or not.
354+
344355
## Machine-Readable Build Output
345356
346357
The build output produced by the `native-image` builder is designed for humans, can evolve with new releases, and should thus not be parsed in any way by tools.
347358
Instead, use the `-H:BuildOutputJSONFile=<file.json>` option to instruct the builder to produce machine-readable build output in JSON format that can be used, for example, for building monitoring tools.
348-
The JSON files validate against the JSON schema defined in [`build-output-schema-v0.9.2.json`](https://github.com/oracle/graal/tree/master/docs/reference-manual/native-image/assets/build-output-schema-v0.9.2.json).
359+
Such a JSON file validates against the JSON schema defined in [`build-output-schema-v0.9.2.json`](https://github.com/oracle/graal/tree/master/docs/reference-manual/native-image/assets/build-output-schema-v0.9.2.json).
349360
Note that a JSON file is produced if and only if a build succeeds.
350361
351362
The following example illustrates how this could be used in a CI/CD build pipeline to check that the number of reachable methods does not exceed a certain threshold:

docs/reference-manual/native-image/MemoryManagement.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Here is a small subset of the options that can be specified when doing performan
164164

165165
```shell
166166
# Build and execute a native image that uses the G1 GC with a region size of 2MB and a maximum pause time goal of 100ms
167-
native-image --gc=G1 -H:G1RegionSize=2m -R:MaxGCPauseMillis=100 HelloWorld
167+
native-image --gc=G1 -H:G1HeapRegionSize=2m -R:MaxGCPauseMillis=100 HelloWorld
168168
./helloworld
169169

170170
# Execute the native image from above and override the maximum pause time goal

docs/reference-manual/native-image/OptimizationsAndPerformance.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,35 @@ permalink: /reference-manual/native-image/optimizations-and-performance/
77

88
# Optimizations and Performance
99

10-
Native Image provides advanced mechanisms to further optimize the generated binary:
10+
Native Image provides different mechanisms that enable users to optimize a generated binary in terms of performance, file size, build time, debuggability, and other metrics.
11+
12+
### Optimization Levels
13+
14+
Similar to `gcc` and `clang`, users can control the optimization level using the `-O` option.
15+
By default, `-O2` is used which aims for a good tradeoff between performance, file size, and build time.
16+
The following table provides an overview of the different optimization levels and explains when they are useful:
17+
18+
| Level | Optimizations | Use Cases |
19+
|:---:|:---:|---|
20+
| `-Ob` | Reduced | Quick build mode: Speeds up builds during development by avoiding time-consuming optimizations. This can also reduce file size sometimes. |
21+
| `-O0` | None | Typically used together with `-g` to improve the debugging experience. |
22+
| `-O1` | Basic | Trades performance for reduced file size and build time. Oracle GraalVM's `-O1` is somewhat comparable to `-O2` in GraalVM Community Edition. |
23+
| `-O2` | Advanced | **Default:** Aims for good performance at a reasonable file size. |
24+
| `-O3` | All | Aims for the best performance at the cost of longer build times. Used automatically by Oracle GraalVM for [PGO builds](guides/optimize-native-executable-with-pgo.md) (`--pgo` option). `-O3` and `-O2` are identical in GraalVM Community Edition. |
25+
26+
### Optimizing for Specific Machines
27+
28+
Native Image provides a `-march` option that works similarly to the ones in `gcc` and `clang`: it enables users to control the set of instructions that the Graal compiler can use when compiling code to native.
29+
By default, Native Image uses [`x86-64-v3` on x64](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels){:target="_blank"} and [`armv8-a` on AArch64](https://en.wikipedia.org/wiki/ARM_architecture_family#Cores){:target="_blank"}.
30+
Use `-march=list` to list all available machine types.
31+
If the generated binary is built on the same or similar machine type that it is also deployed on, use `-march=native`.
32+
This option instructs the compiler to use all instructions that it finds available on the machine the binary is generated on.
33+
If the generated binary, on the other hand, is distributed to users with many different, and potentially very old machines, use `-march=compatibility`.
34+
This reduces the set of instructions used by the compiler to a minimum and thus improves the compatibility of the generated binary.
35+
36+
### Additional Features
37+
38+
Native Image provides additional features to further optimize a generated binary:
1139

1240
- Profile-Guided Optimizations (PGO) can provide additional performance gain and higher throughput for most native images. See [Optimize a Native Executable with PGO](guides/optimize-native-executable-with-pgo.md).
1341
- Choosing an appropriate Garbage Collector and tailoring the garbage collection policy can reduce GC times. See [Memory Management](MemoryManagement.md).

docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"title": "Relative path to file or directory",
1212
"type": "string"
1313
},
14-
"title": "Build information generated by Native Image (not needed at run-time)",
14+
"title": "Build information generated by Native Image (not needed at run time)",
1515
"type": "array"
1616
},
1717
"c_headers": {
@@ -21,7 +21,7 @@
2121
"title": "Relative path to file or directory",
2222
"type": "string"
2323
},
24-
"title": "C header files generated by Native Image (not needed at run-time)",
24+
"title": "C header files generated by Native Image (not needed at run time)",
2525
"type": "array"
2626
},
2727
"debug_info": {
@@ -31,7 +31,7 @@
3131
"title": "Relative path to file or directory",
3232
"type": "string"
3333
},
34-
"title": "Debug information generated by Native Image (not needed at run-time)",
34+
"title": "Debug information generated by Native Image (not needed at run time)",
3535
"type": "array"
3636
},
3737
"executables": {
@@ -41,7 +41,7 @@
4141
"title": "Relative path to file or directory",
4242
"type": "string"
4343
},
44-
"title": "Executables generated by Native Image (needed at run-time)",
44+
"title": "Executables generated by Native Image (needed at run time)",
4545
"type": "array"
4646
},
4747
"import_libraries": {
@@ -51,7 +51,7 @@
5151
"title": "Relative path to file or directory",
5252
"type": "string"
5353
},
54-
"title": "Import libraries generated by Native Image (not needed at run-time)",
54+
"title": "Import libraries generated by Native Image (not needed at run time)",
5555
"type": "array"
5656
},
5757
"jdk_libraries": {
@@ -61,7 +61,7 @@
6161
"title": "Relative path to file or directory",
6262
"type": "string"
6363
},
64-
"title": "JDK libraries copied by Native Image (needed at run-time)",
64+
"title": "JDK libraries copied by Native Image (needed at run time)",
6565
"type": "array"
6666
},
6767
"language_home": {
@@ -71,7 +71,7 @@
7171
"title": "Relative path to file or directory",
7272
"type": "string"
7373
},
74-
"title": "Language home artifacts for Truffle languages (needed at run-time)",
74+
"title": "Language home artifacts for Truffle languages (needed at run time)",
7575
"type": "array"
7676
},
7777
"shared_libraries": {
@@ -81,7 +81,7 @@
8181
"title": "Relative path to file or directory",
8282
"type": "string"
8383
},
84-
"title": "Shared libraries generated by Native Image (not needed at run-time)",
84+
"title": "Shared libraries generated by Native Image (needed at run time)",
8585
"type": "array"
8686
}
8787
},

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ private void printArtifacts(Map<ArtifactType, List<Path>> artifacts) {
779779
return;
780780
}
781781
l().printLineSeparator();
782-
l().yellowBold().a("Produced artifacts:").reset().println();
782+
l().yellowBold().doclink("Build artifacts", "#glossary-build-artifacts").a(":").reset().println();
783783
// Use TreeMap to sort paths alphabetically.
784784
Map<Path, List<String>> pathToTypes = new TreeMap<>();
785785
artifacts.forEach((artifactType, paths) -> {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUType.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
2626

2727
import java.util.Arrays;
2828
import java.util.Comparator;
29+
import java.util.List;
2930

3031
import org.graalvm.nativeimage.Platform;
3132

@@ -86,4 +87,8 @@ static String getSelectedOrDefaultMArch() {
8687
return "unknown";
8788
}
8889
}
90+
91+
static List<String> toNames(CPUType[] values) {
92+
return Arrays.stream(values).map(CPUType::getName).toList();
93+
}
8994
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAArch64.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -133,7 +133,7 @@ public static EnumSet<CPUFeature> getCPUFeaturesForArch(String marchValue) {
133133
throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On AArch64, only %s are available.",
134134
marchValue,
135135
SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue),
136-
StringUtil.joinSingleQuoted(values()));
136+
StringUtil.joinSingleQuoted(CPUType.toNames(values())));
137137
}
138138
List<CPUFeature> features = new ArrayList<>(value.getFeatures());
139139
processFeatureModifiers(features, archParts);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -177,7 +177,7 @@ public static EnumSet<CPUFeature> getCPUFeaturesForArch(String marchValue) {
177177
throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On AMD64, only %s are available.",
178178
marchValue,
179179
SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue),
180-
StringUtil.joinSingleQuoted(values()));
180+
StringUtil.joinSingleQuoted(CPUType.toNames(values())));
181181
}
182182
return value.getFeatures();
183183
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@ private static CPUFeature[] getNativeOrEmpty() {
9191
name = cpuTypeName;
9292
parent = cpuTypeParentOrNull;
9393
specificFeatures = features.length > 0 ? EnumSet.copyOf(List.of(features)) : EnumSet.noneOf(CPUFeature.class);
94-
assert parent == null || parent.getFeatures().stream().noneMatch(f -> specificFeatures.contains(f)) : "duplicate features detected but not allowed";
94+
assert parent == null || parent.getFeatures().stream().noneMatch(specificFeatures::contains) : "duplicate features detected but not allowed";
9595
}
9696

9797
@Override
@@ -106,7 +106,7 @@ public CPUTypeRISCV64 getParent() {
106106

107107
@Override
108108
public String getSpecificFeaturesString() {
109-
return specificFeatures.stream().map(f -> f.name()).collect(Collectors.joining(" + "));
109+
return specificFeatures.stream().map(Enum::name).collect(Collectors.joining(" + "));
110110
}
111111

112112
public EnumSet<CPUFeature> getFeatures() {
@@ -136,7 +136,7 @@ public static EnumSet<CPUFeature> getCPUFeaturesForArch(String marchValue) {
136136
throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On RISCV64, only %s are available.",
137137
marchValue,
138138
SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue),
139-
StringUtil.joinSingleQuoted(values()));
139+
StringUtil.joinSingleQuoted(CPUType.toNames(values())));
140140
}
141141
return value.getFeatures();
142142
}

0 commit comments

Comments
 (0)