This project provides a C interface for managing Intel Running Average Power Limit (RAPL) power caps.
RAPLCap is primarily intended for use by researchers and software developers.
Most Linux users and system administrators looking to manage RAPL should prefer the powercap-info and powercap-set command-line utilities from the powercap project.
RAPLCap supports multiple implementations with different backends:
libraplcap-msr(README): Uses Model-Specific Register files in the/devfilesystem (Linux).libraplcap-powercap(README): Uses the Linux Power Capping Framework abstractions in the/sysfilesystem (Linux).
It also provides binaries for getting/setting RAPL configurations from the command line. Each provides the same command line interface, but use different RAPLCap library backends.
rapl-configure-msrrapl-configure-powercap
If using this project for other scientific works or publications, please reference:
-
Connor Imes, Huazhe Zhang, Kevin Zhao, Henry Hoffmann. "CoPPer: Soft Real-time Application Performance Using Hardware Power Capping". In: IEEE International Conference on Autonomic Computing (ICAC). 2019. DOI: https://doi.org/10.1109/ICAC.2019.00015
BibTex
@inproceedings{imes2019copper, author={Imes, Connor and Zhang, Huazhe and Zhao, Kevin and Hoffmann, Henry}, booktitle={2019 IEEE International Conference on Autonomic Computing (ICAC)}, title={{CoPPer}: Soft Real-Time Application Performance Using Hardware Power Capping}, year={2019}, pages={31-41}, doi={10.1109/ICAC.2019.00015} }
First, you must be using an Intel® processor that supports RAPL - Sandy Bridge (2nd generation Intel® Core) or newer.
Currently only Linux systems are supported by the primary implementations.
This project depends on:
- powercap - backend required to compile and run the
powercapimplementation (or install the libpowercap-dev package on recent Debian-based Linux distributions).
If dependencies with sufficient versions are not found, backends that require them will not be compiled.
Users are expected to be familiar with basic RAPL capabilities and terminology, like zones (domains) and long/short term power constraints. Refer to Intel RAPL documentation for more technical information, especially the Intel® 64 and IA-32 Architectures Software Developer Manual, Volume 3: System Programming Guide.
Due to lack of portability in backends and data availability on some systems, the interface does not support discovering processor min/max power caps or thermal design power. Users should reference their hardware documentation or other system utilities to discover this information as needed.
Intel RAPL allows software to configure power caps on hardware components, like processors or main memory. Components manage themselves to respect the power cap while attempting to optimize performance. Note that power caps are NOT the same as power consumption, they only specify an upper bound on power consumption over a time window.
For example, processors use Dynamic Voltage and Frequency Scaling (DVFS) to trade performance and power consumption, where power P is proportional to capacitance C, the square of the voltage V, and clock frequency f: P ~ C * V^2 * f.
An increase in frequency usually necessitates an increase in voltage, and vice versa, resulting in a non-linear tradeoff between performance (frequency) and power consumption.
With RAPL, hardware manages voltage and frequency at finer-grained time intervals and with lower overhead than software-based DVFS controllers.
This project uses CMake.
To build all libraries, run:
mkdir _build
cd _build
cmake ..
makeTo install all libraries and headers, run with proper privileges:
make installOn Linux, installation typically places libraries in /usr/local/lib and header files in /usr/local/include.
Install must be run before uninstalling in order to have a manifest.
To remove libraries and headers installed to the system, run with proper privileges:
make uninstallIf your project uses CMake, import targets from the RAPLCap package by specifying the MSR and/or Powercap components as needed.
For example:
find_package(RAPLCap REQUIRED COMPONENTS MSR Powercap)
target_link_libraries(foo PRIVATE RAPLCap::raplcap-msr)
target_link_libraries(bar PRIVATE RAPLCap::raplcap-powercap)If not using CMake, get linker information (including transitive dependencies) with pkg-config, e.g., one of:
pkg-config --libs --static raplcap-msr
pkg-config --libs --static raplcap-powercapOr in your Makefile, add to your linker flags one of:
$(shell pkg-config --libs --static raplcap-msr)
$(shell pkg-config --libs --static raplcap-powercap)You may leave off the --static option if you built shared object libraries.
Depending on your install location, you may also need to augment your compiler flags with one of:
pkg-config --cflags raplcap-msr
pkg-config --cflags raplcap-powercapSee the man pages for the rapl-configure binaries, or run them with the -h or --help option for instructions.
The raplcap.h header provides the C interface along with detailed function documentation for using the libraries.
For backend-specific runtime dependencies, see the README files in their implementation subdirectories (links above).
The following is a simple example of setting power caps that assumes a homogeneous architecture.
// Note: more robust error handling may be desirable for a real application
raplcap rc;
raplcap_limit rl_short, rl_long;
uint32_t i, j, n, d;
// get the number of RAPL packages
n = raplcap_get_num_packages(NULL);
if (n == 0) {
perror("raplcap_get_num_packages");
return -1;
}
// initialize
if (raplcap_init(&rc)) {
perror("raplcap_init");
return -1;
}
// assuming each package has the same number of die, only querying for package=0
d = raplcap_get_num_die(rc, 0);
if (d == 0) {
perror("raplcap_get_num_die");
raplcap_destroy(&rc);
return -1;
}
// for each package die, set a power cap of 100 Watts for short_term and 50 Watts for long_term constraints
// a time window of 0 leaves the time window unchanged
rl_short.watts = 100.0;
rl_short.seconds = 0.0;
rl_long.watts = 50.0;
rl_long.seconds = 0.0;
for (i = 0; i < n; i++) {
for (j = 0; j < d; j++) {
if (raplcap_pd_set_limits(&rc, i, j, RAPLCAP_ZONE_PACKAGE, &rl_long, &rl_short)) {
perror("raplcap_pd_set_limits");
}
}
}
// for each package die, enable the power caps
// this could be done before setting caps, at the risk of enabling unknown power cap values first
for (i = 0; i < n; i++) {
for (j = 0; j < d; j++) {
if (raplcap_pd_set_zone_enabled(&rc, i, j, RAPLCAP_ZONE_PACKAGE, 1)) {
perror("raplcap_pd_set_zone_enabled");
}
}
}
// cleanup
if (raplcap_destroy(&rc)) {
perror("raplcap_destroy");
}Find this and related project sources at the powercap organization on GitHub.
This project originates at: https://github.com/powercap/raplcap
Bug reports and pull requests for new implementations, bug fixes, and enhancements are welcome.