Migration Readiness Methodology¶
This guide assumes maintaining a report to document key findings for each project under study. Nearly every section is highlighted for inclusion in the report
Version: 0.1.0
Finding the active repository:
check the dates of the latest commits and issues
review the description and README in case the project was moved to another repository as part of a larger project (e.g.,
RapidXMLmoved toBoost); in that case, check if the project can be built standalone, without the parent projectcheck for other repositories maintained and developed by other developers; if two forks evolve in parallel, one version may be more advanced
look for stable releases, GitHub version tags, etc.
also see Debian, Arch, Yocto patches, etc.
After selecting an active repository, examine its structure and assess maintainability and complexity:
presence of tests, CI, build systems, documentation, benchmarks
presence of vectorization macros and other platform-dependent macros in the code; verify their semantics — macro names can sometimes be misleading
assess dependencies:
dependency count
for each dependency check its migration readiness status in database (any resource that contains information about project portability); if project is missing, add the issue in the report, evaluate the portability of this dependency on explored architecture and release your result in the database and report
summarize over all dependencies
To evaluate package behavior on the explored architecture, build and verify it on the main platform where the project is distributing (typically x86):
build with debug info, optimizations, maybe options for building tests: for optimizations use
-O3and-march=<native or supported extensions>options for C/C++; use-march=nativefor native compilation, otherwise specify for concrete platform: some RISC-V CPUs with partial RVA23 support may have something likerv64gc_zba_zbb_zbc_zbs_<...>extension, — you can find this information ingccorg++via-Q --help=targetoptions, see “Known valid arguments for -march= option”; forclangandclang++you can see supported targets via--print-targetsoption and supported extensions via--target=<target> --print-supported-extensionsoptionsbuild tests using available methods: usually a config option (like
-DYAML_CPP_BUILD_TESTS=onforyaml-cpp) or build target (make test)verify functionality: run tests; if they fail, consult documentation or issues; document findings; report bugs to developers if not already done (e.g., file an issue or submit a patch)
Repeat steps from previous paragraph for explored platform.
For profiling on each platform use
perf statandperf record:ensure experimental rigor:
Pin the process to a high-performance core (
taskset -c <performance_core_number> <your_executable>on Linux)Set highest priority (
nice -n -20 <your_executable>on Linux, requires root)Turn off CPU Turbo Boost for fixing frequency: in Linux for Intel you can write 1 to each state for each core in
/sys/devices/system/cpu/cpu<core number>/cpuidle/state<state number>/disableand/sys/devices/system/cpu/intel_pstate/no_turbo; check current frequency viacat /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq
prefer benchmarks over tests for more illustrative results; if test runtime depends on dataset size, try increasing it
before measuring of performance do warmup run: 10-15% of planned runs for performance measurement; it loads the CPU cache, allows Branch-Predictor to learn, stabilizes background processes
run
perf statvia the following commandnice -n -20 taskset -c <performance_core_number> perf stat -ddd <your_executable> # -ddd (triple -d) gives more info
From its output, pay attention to elapsed time, cache-misses, branches (branch-misses), and color-highlighted metrics
run
perf recordvia the commandnice -n -20 taskset -c <performance_core_number> perf record <your_executable>
After collecting samples, view execution statistics with
perf reportcompare execution traces across all build variants: run each build at least 6-10 times to get averaged numbers
also you can use
perf stat --repeat Nfor N runs and use--tablewith it to create a table of measurementscompare builds for the target architecture against a reference platform; include the comparison in the report
Attempt to optimize bottlenecks:
use your toolchain’s
objdumpto look for platform vector instructions; if none found, try compiler vectorization flags (-ftree-vectorizeforgcc/g++); if that doesn’t help, try a newer toolchain (from your distro repos, specialized vendors like Syntacore, or configure one yourself withcrosstool-NG); if the project has dependencies that need to be separately downloaded into the toolchain root, trydebootstrap(on Debian-family distros) orbuildroottry compile toolchain with static linked
libc/libc++for each platformtry a different memory allocator:
mimalloc,jemalloc,tcmalloc, etc.; if the issue involves heavyfreeordeletecalls, use arena allocatorsbuild the project with LTO (Link Time Optimization)
try optimizing high-load areas identified from
perf reportoutput
Share your results, and may the Open Source be with you!