Merge branch 'pgo-script'

Closes #701
This commit is contained in:
Daniel Eklöf 2021-09-12 19:11:44 +02:00
commit f9d968b4c7
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
11 changed files with 258 additions and 74 deletions

View file

@ -36,6 +36,9 @@
* Warn when it appears the primary font is not monospaced. Can be
disabled by setting `[tweak].font-monospace-warn=no`
(https://codeberg.org/dnkl/foot/issues/704).
* PGO build scripts, in the `pgo` directory. See INSTALL.md -
_Performance optimized, PGO_, for details
(https://codeberg.org/dnkl/foot/issues/701).
### Changed

View file

@ -274,6 +274,32 @@ slower!) binary.
#### Performance optimized, PGO
There are a lot more steps involved in a PGO build, and for this
reason there are a number of helper scripts available.
`pgo/pgo.sh` is a standalone script that pieces together the other
scripts in the `pgo` directory to do a complete PGO build. This script
is intended to be used when doing manual builds.
Example:
```sh
cd foot
./pgo/pgo.sh auto . /tmp/foot-pgo-build-output
```
(run `./pgo/pgo.sh` to get help on usage)
It supports a couple of different PGO builds; partial (covered in
detail below), full (also covered in detail below), and (full)
headless builds using Sway or cage.
Packagers may want to use it as inspiration, but may choose to support
only a specific build type; e.g. full/headless with Sway.
To do a manual PGO build, instead of using the script(s) mentioned
above, detailed instructions follows:
First, configure the build directory:
```sh

View file

@ -1,3 +1,5 @@
PGO=auto # auto|none|partial|full-current-session|full-headless-sway|full-headless-cage
pkgname=('foot-git' 'foot-terminfo-git')
pkgver=1.9.0
pkgrel=1
@ -14,80 +16,7 @@ pkgver() {
}
build() {
local compiler=other
local do_pgo=no
# makepkg uses -O2 by default, but we *really* want -O3
CFLAGS+=" -O3"
# Figure out which compiler we're using, and whether or not to do PGO
case $(${CC-cc} --version) in
*GCC*)
compiler=gcc
do_pgo=yes
;;
*clang*)
compiler=clang
# We need llvm to be able to manage the profiling data
if command -v llvm-profdata > /dev/null; then
do_pgo=yes
# Meson adds -fprofile-correction, which Clang doesn't
# understand
CFLAGS+=" -Wno-ignored-optimization-argument"
fi
;;
esac
meson \
--prefix=/usr \
--buildtype=release \
--wrap-mode=nofallback \
-Db_lto=true ..
if [[ ${do_pgo} == yes ]]; then
find -name "*.gcda" -delete
meson configure -Db_pgo=generate
ninja
# If fcft/tllist are subprojects, we need to ensure their tests
# have been executed, or well get “profile count data file not
# found” errors.
ninja test
local script_options="--scroll --scroll-region --colors-regular --colors-bright --colors-256 --colors-rgb --attr-bold --attr-italic --attr-underline --sixel"
tmp_file=$(mktemp)
if [[ -v WAYLAND_DISPLAY ]]; then
./footclient --version
./foot \
--config /dev/null \
--term=xterm \
sh -c "../scripts/generate-alt-random-writes.py ${script_options} ${tmp_file} && cat ${tmp_file}"
else
./footclient --version
./foot --version
../scripts/generate-alt-random-writes.py \
--rows=67 \
--cols=135 \
${script_options} \
${tmp_file}
./pgo ${tmp_file} ${tmp_file} ${tmp_file}
fi
rm "${tmp_file}"
if [[ ${compiler} == clang ]]; then
llvm-profdata merge default_*profraw --output=default.profdata
fi
meson configure -Db_pgo=use
fi
ninja
../pgo/pgo.sh ${PGO} .. . --prefix=/usr --wrap-mode=nofallback
}
check() {

8
pgo/full-current-session.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/sh
set -eux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
"${srcdir}"/pgo/full-inner.sh "${srcdir}" "${blddir}"

14
pgo/full-headless-cage.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/sh
set -eux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
runtime_dir=$(mktemp -d)
trap "rm -rf '${runtime_dir}'" EXIT INT HUP TERM
XDG_RUNTIME_DIR="${runtime_dir}" WLR_BACKENDS=headless cage "${srcdir}"/pgo/full-inner.sh "${srcdir}" "${blddir}"
# Cages exit code doesnt reflect our scripts exit code
[ -f "${blddir}"/pgo-ok ] || exit 1

View file

@ -0,0 +1,9 @@
#!/bin/sh
set -ux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
"${srcdir}"/pgo/full-inner.sh "${srcdir}" "${blddir}"
swaymsg exit

24
pgo/full-headless-sway.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh
set -eux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
runtime_dir=$(mktemp -d)
sway_conf=$(mktemp)
cleanup() {
rm -f "${sway_conf}"
rm -rf "${runtime_dir}"
}
trap cleanup EXIT INT HUP TERM
# Generate a custom config that executes our generate-pgo-data script
> "${sway_conf}" echo "exec '${srcdir}'/pgo/full-headless-sway-inner.sh '${srcdir}' '${blddir}'"
# Run Sway. full-headless-sway-inner.sh ends with a swaymsg exit
XDG_RUNTIME_DIR="${runtime_dir}" WLR_BACKENDS=headless sway -c "${sway_conf}"
# Sways exit code doesnt reflect our scripts exit code
[ -f "${blddir}"/pgo-ok ] || exit 1

30
pgo/full-inner.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh
set -eux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
. "${srcdir}"/pgo/options
pgo_data=$(mktemp)
trap "rm -f '${pgo_data}'" EXIT INT HUP TERM
rm -f "${blddir}"/pgo-ok
# To ensure profiling data is generated in the build directory
cd "${blddir}"
LC_CTYPE=en_US.UTF-8 "${blddir}"/footclient --version
LC_CTYPE=en_US.UTF-8 "${blddir}"/foot \
--config=/dev/null \
--term=xterm \
sh -c "
set -eux
'${srcdir}/scripts/generate-alt-random-writes.py' \
${script_options} \"${pgo_data}\"
cat \"${pgo_data}\"
"
touch "${blddir}"/pgo-ok

1
pgo/options Normal file
View file

@ -0,0 +1 @@
script_options="--scroll --scroll-region --colors-regular --colors-bright --colors-256 --colors-rgb --attr-bold --attr-italic --attr-underline --sixel"

28
pgo/partial.sh Executable file
View file

@ -0,0 +1,28 @@
#!/bin/sh
set -eux
srcdir=$(realpath "${1}")
blddir=$(realpath "${2}")
. "${srcdir}"/pgo/options
pgo_data=$(mktemp)
trap "rm -f ${pgo_data}" EXIT INT HUP TERM
rm -f "${blddir}"/pgo-ok
"${srcdir}"/scripts/generate-alt-random-writes.py \
--rows=67 \
--cols=135 \
${script_options} \
"${pgo_data}"
# To ensure profiling data is generated in the build directory
cd "${blddir}"
"${blddir}"/footclient --version
"${blddir}"/foot --version
"${blddir}"/pgo "${pgo_data}"
touch "${blddir}"/pgo-ok

112
pgo/pgo.sh Executable file
View file

@ -0,0 +1,112 @@
#!/bin/sh
set -eu
usage_and_die() {
echo "Usage: ${0} none|partial|full-current-session|full-headless-sway|full-headless-cage|[auto] <source-dir> <build-dir> [meson options]"
exit 1
}
[ ${#} -ge 3 ] || usage_and_die
mode=${1}
srcdir=$(realpath "${2}")
blddir=$(realpath "${3}")
shift 3
# if [ -e "${blddir}" ]; then
# echo "error: ${blddir}: build directory already exists"
# exit 1
# fi
compiler=other
do_pgo=no
CFLAGS="${CFLAGS-} -O3"
case $(${CC-cc} --version) in
*GCC*)
compiler=gcc
do_pgo=yes
;;
*clang*)
compiler=clang
if command -v llvm-profdata > /dev/null; then
do_pgo=yes
CFLAGS="${CFLAGS} -Wno-ignored-optimization-argument"
fi
;;
esac
case ${mode} in
partial|full-current-session|full-headless-sway|full-headless-cage)
;;
none)
do_pgo=no
;;
auto)
# TODO: once Sway 1.6.2 has been released, prefer
# full-headless-sway
if [ -n "${WAYLAND_DISPLAY+x}" ]; then
mode=full-current-session
# elif command -v sway > /dev/null; then # Requires 1.6.2
# mode=full-headless-sway
elif command -v cage > /dev/null; then
mode=full-headless-cage
else
mode=partial
fi
;;
*)
usage_and_die
;;
esac
set -x
# echo "source: ${srcdir}"
# echo "build: ${blddir}"
# echo "compiler: ${compiler}"
# echo "mode: ${mode}"
# echo "CFLAGS: ${CFLAGS}"
export CFLAGS
meson setup --buildtype=release -Db_lto=true "${@}" "${blddir}" "${srcdir}"
if [ ${do_pgo} = yes ]; then
find "${blddir}" \
'(' \
-name "*.gcda" -o \
-name "*.profraw" -o \
-name default.profdata \
')' \
-delete
meson configure "${blddir}" -Db_pgo=generate
ninja -C "${blddir}"
# If fcft/tllist are subprojects, we need to ensure their tests
# have been executed, or well get “profile count data file not
# found” errors.
ninja -C "${blddir}" test
# Run mode-dependent script to generate profiling data
"${srcdir}"/pgo/${mode}.sh "${srcdir}" "${blddir}"
if [ ${compiler} = clang ]; then
llvm-profdata \
merge \
"${blddir}"/default_*.profraw \
--output="${blddir}"/default.profdata
fi
meson configure "${blddir}" -Db_pgo=use
fi
ninja -C "${blddir}"