GithubHelp home page GithubHelp logo

powercap / powercap Goto Github PK

View Code? Open in Web Editor NEW
52.0 3.0 7.0 326 KB

C bindings to the Linux Power Capping Framework in sysfs

License: BSD 3-Clause "New" or "Revised" License

CMake 4.01% C 87.96% Roff 8.03%
powercap rapl sysfs linux c power-management

powercap's Introduction

Powercap Sysfs C Bindings and Utilities

This project provides the powercap library -- a generic C interface to the Linux power capping framework (sysfs interface). It also provides the following applications:

  • powercap-info - view powercap control type hierarchies or zone/constraint-specific configurations
  • powercap-set - set powercap control type zone/constraint-specific configurations

The aforementioned library and applications should be compatible with all Linux powercap drivers. The library also includes an API, originally created for use with RAPLCap, specifically for managing Intel Running Average Power Limit (RAPL).

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}
    }

Prerequisites

The Linux power capping framework was released with Linux kernel 3.13. You must be running this kernel or newer with the configs CONFIG_POWERCAP and CONFIG_INTEL_RAPL enabled to use the Intel RAPL driver.

To use the intel-rapl control type, ensure that the appropriate kernel module is loaded. Run with proper privileges:

modprobe intel_rapl_msr

Or on kernels older than 5.3:

modprobe intel_rapl

Power Capping

Modern hardware is constrained by power and temperature limitations, often quantified as Thermal Design Power. In processors and other clock-driven hardware components, power consumption P is proportional to capacitance C, the square of the voltage V, and clock frequency f: P ~ C * V^2 * f. A popular mechanism for balancing performance and power consumption is Dynamic Voltage and Frequency Scaling (DVFS). For compute-bound applications, DVFS provides a linear relationship between frequency and performance. However, power is non-linear with frequency since an increase in frequency also requires an increase in voltage.

Although the relationship between performance and power is more difficult to model, hardware can be better at optimizing voltage and frequency than software while still respecting a power cap over a time window. Power capping allows a system administrator to configure an upper limit on the power consumption of various hardware components while letting the hardware more efficiently manage voltage and frequency. Setting a power cap does NOT imply that the component will actually consume that power, only that it will not violate that limit on average over the specified time window.

Usage

Applications

See the man pages or run the applications with the -h or --help option for instructions.

Library

First, there is the powercap-sysfs.h interface for reading/writing to sysfs without the need to maintain state. This is reasonable for simple use cases. See the header files for documentation.

The powercap.h interface provides read/write functions for generic powercap zone and constraint file sets. Users are responsible for managing memory and populating the structs with file descriptors (e.g., code that wrap this interface performs zone/constraint discovery and file descriptor management).

The powercap-rapl.h interface discovers RAPL instances, power zones, and constraints (i.e., long_term and short_term constraints). Users are responsible for managing memory, but the library will manage discovering, opening, and closing files within instances.

Basic lifecycle example:

  // get number of top-level (parent) RAPL instances
  uint32_t count = powercap_rapl_get_num_instances();
  if (count == 0) {
    // none found (maybe the kernel module isn't loaded?)
    perror("powercap_rapl_get_num_instances")
    return -1;
  }
  powercap_rapl_pkg* pkgs = malloc(count * sizeof(powercap_rapl_pkg));
  // initialize
  uint32_t i;
  for (i = 0; i < count; i++) {
    if (powercap_rapl_init(i, &pkgs[i], 0)) {
      // could be that you don't have write privileges
      perror("powercap_rapl_init");
      return -1;
    }
  }
  // do a bunch of stuff with the interface here,
  // e.g., enable desired zones and get/set power caps...
  // now cleanup
  for (i = 0; i < count; i++) {
    if (powercap_rapl_destroy(&pkgs[i])) {
      perror("powercap_rapl_destroy");
    }
  }
  free(pkgs);

Additional Comments

The interfaces do NOT guarantee that values are actually accepted by the kernel, they only notice errors if I/O operations fail. It is recommended that, at least during development/debugging, users read back to see if their write operations were successful.

Additionally, the kernel sysfs bindings (and thus the powercap-rapl interface) do NOT guarantee that RAPL instances are presented in any particular order. For example, the first instance (sysfs directory intel-rapl:0) on a dual-socket system may actually provide access to package-1 instead of package-0, and vice versa. In cases where order matters, e.g., when sockets are managed asymmetrically, the user is responsible for ensuring that the correct powercap instance is being operated on, e.g., by checking its name with powercap_rapl_get_name(...). More concretely, in the example above, powercap_rapl_get_name(&pkgs[0], POWERCAP_RAPL_ZONE_PACKAGE, ...) gives name package-1, and powercap_rapl_get_name(&pkgs[1], POWERCAP_RAPL_ZONE_PACKAGE, ...) is package-0. It might be helpful to sort the pkgs array after initialization (see the powercap implementation of RAPLCap for an example).

Finally, the powercap-rapl interface exposes functions for files that are not (currently) supported by RAPL in order to be compliant with the powercap interface. Use the powercap_rapl_is_zone_file_supported(...) and powercap_rapl_is_constraint_file_supported(...) functions to check in advance if you are unsure if a zone or constraint file is supported. Furthermore, files may exist but always return an error code for some zones or constraints, e.g., the constraint max_power_uw file (powercap_rapl_get_max_power_uw(...)) for zones other than POWERCAP_RAPL_ZONE_PACKAGE.

Building

Compiling

This project uses CMake.

To build, run:

mkdir _build
cd _build
cmake ..
make

To create a shared object library as a release build, specify for cmake:

cmake .. -DBUILD_SHARED_LIBS=On -DCMAKE_BUILD_TYPE=Release

Installing

To install, run with proper privileges:

make install

On Linux, installation typically places libraries in /usr/local/lib and header files in /usr/local/include.

Uninstalling

Install must be run before uninstalling in order to have a manifest. To uninstall, run with proper privileges:

make uninstall

Cross Compiling

To cross-compile for different systems/architectures, use standard CMake toolchain files. See Mastering CMake for reference.

For example, modify the cmake command from the build directory to use your own toolchain.cmake file:

cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake ..

Project Source

Find this and related project sources at the powercap organization on GitHub.
This project originates at: https://github.com/powercap/powercap

Bug reports and pull requests for bug fixes and enhancements are welcome.

License

This project is developed by Connor Imes. It is released under the 3-Clause BSD License.

Thanks

Special thanks to Henry Hoffmann (University of Chicago) and Steven Hofmeyr (Lawrence Berkeley National Laboratory) for advising and supporting projects that this code was originally developed for.

powercap's People

Contributors

alexshpilkin avatar connorimes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

powercap's Issues

Kernel uses hexadecimal numbers in directory paths, not decimal

On systems that have >10 zones, the kernel prints values in directory names using lower case hex. So as of now, libpowercap and its utilities do not support >10 instances because it expects decimal values in the directory names.

For example, after intel-rapl:9/ comes intel-rapl:a/ instead of intel-rapl:10/.

The pattern applies to subzones as well, which inherit paths from the parent, e.g. intel-rapl:a/intel-rapl:a:0/

Constraint numbers in filenames are still decimal though.

Add support for MMIO RAPL

MMIO RAPL support as Intel processor_thermal device exposes the
capability to do RAPL control via MMIO registers.

ls -la /sys/devices/virtual/powercap/intel-rapl-mmio/intel-rapl-mmio:0
total 0
drwxr-xr-x 3 root root    0 апр  7 04:31 .
drwxr-xr-x 4 root root    0 апр  7 04:31 ..
-r--r--r-- 1 root root 4096 апр  7 05:34 constraint_0_max_power_uw
-r--r--r-- 1 root root 4096 апр  7 05:34 constraint_0_name
-rw-r--r-- 1 root root 4096 апр  7 13:53 constraint_0_power_limit_uw
-rw-r--r-- 1 root root 4096 апр  7 05:34 constraint_0_time_window_us
-r--r--r-- 1 root root 4096 апр  7 05:34 constraint_1_max_power_uw
-r--r--r-- 1 root root 4096 апр  7 05:34 constraint_1_name
-rw-r--r-- 1 root root 4096 апр  7 05:34 constraint_1_power_limit_uw
-rw-r--r-- 1 root root 4096 апр  7 05:34 constraint_1_time_window_us
lrwxrwxrwx 1 root root    0 апр  7 05:34 device -> ../../intel-rapl-mmio
-rw-r--r-- 1 root root 4096 апр  7 05:34 enabled
-r--r--r-- 1 root root 4096 апр  7 05:34 energy_uj
-r--r--r-- 1 root root 4096 апр  7 05:34 max_energy_range_uj
-r--r--r-- 1 root root 4096 апр  7 05:34 name
drwxr-xr-x 2 root root    0 апр  7 05:34 power
lrwxrwxrwx 1 root root    0 апр  7 04:31 subsystem -> ../../../../../class/powercap
-rw-r--r-- 1 root root 4096 апр  7 04:31 uevent

RAPL zone hierarchy

Dear developers,

could you please help me grasp the logic behind RAPL zone hierarchy?

E.g., on my laptop (i7-8550U) I have the following layout:

|-intel-rapl:0 package      ->  (CPU socket)
| |-- intel-rapl:0:0 cores  ->  (CPU cores)
| |-- intel-rapl:0:1 uncore ->  (integrated graphics etc.)
| |-- intel-rapl:0:2 DRAM   ->  (memory, per socket, but *not* included in package value above)
|-intel-rapl:1 psys         ->  (whole system, ie includes package and DRAM)

Do I understand correctly that energy_uj value for the package zone also includes cores and uncore, but does not include DRAM? And that psys value includes package and DRAM?
It looks, well, counter-intuitive, but seems to be the case according to my observations...

Background: I'm trying to implement energy consumption monitoring for my program, and so I'm interested in the overall system power. RAPL sysfs seems to be the only practical option, since it does not require root privileges. So it looked simple and straightforward, until I realized that I cannot just add up values from all zones to get system-wide power/energy.

Many thanks in advance! I understand that this question is not directly related to your code, but your help will be greatly appreciated!

Alexey

ppc64el build of powercap 0.3.0-1 in ubuntu fails in unit test

See: https://launchpad.net/ubuntu/+source/powercap/0.3.0-1/+build/20207686
Build log: https://launchpadlibrarian.net/504223851/buildlog_ubuntu-hirsute-ppc64el.powercap_0.3.0-1_BUILDING.txt.gz

The relevant part of the build log:

   dh_auto_test -a
	cd obj-powerpc64le-linux-gnu && make -j4 test ARGS\+=-j4
make[1]: Entering directory '/<<PKGBUILDDIR>>/obj-powerpc64le-linux-gnu'
Running tests...
/usr/bin/ctest --force-new-ctest-process -j4
Test project /<<PKGBUILDDIR>>/obj-powerpc64le-linux-gnu
    Start 1: powercap-common-test
    Start 2: powercap-test
    Start 3: powercap-sysfs-test
1/3 Test #2: powercap-test ....................   Passed    0.00 sec
2/3 Test #3: powercap-sysfs-test ..............   Passed    0.00 sec
3/3 Test #1: powercap-common-test .............Child aborted***Exception:   0.17 sec
powercap-common-test: /<<PKGBUILDDIR>>/test/powercap-common-test.c:46: test_snprintf_base_path: Assertion `rc >= 0 && (size_t) rc > sizeof(path)' failed.


67% tests passed, 1 tests failed out of 3

Total Test time (real) =   0.17 sec

The following tests FAILED:
	  1 - powercap-common-test (Child aborted)
Errors while running CTest
make[1]: *** [Makefile:121: test] Error 8
make[1]: Leaving directory '/<<PKGBUILDDIR>>/obj-powerpc64le-linux-gnu'
dh_auto_test: error: cd obj-powerpc64le-linux-gnu && make -j4 test ARGS\+=-j4 returned exit code 2
make: *** [debian/rules:13: binary-arch] Error 25
dpkg-buildpackage: error: debian/rules binary-arch subprocess returned exit status 2

powercap-rapl: psys is a parent zone, not a subzone

The powercap-rapl interface currently assumes that the PACKAGE zone is always the parent zone, and that PSYS is a subzone. As seen in #3, this is not the case. I don't have a system with a PSYS zone, but I expect the powercap-rapl interface would currently treat a PSYS zone as if it were a PACKAGE zone without any subzones.

More generally, the powercap-rapl interfaces makes some assumptions that have proven incorrect or may not hold in the future, so API changes will be needed to address these problems correctly.

pkg-config file is broken when CMAKE_INSTALL_{INCLUDE,LIB}DIR is absolute

As per title: CMakeLists.txt has

set(PKG_CONFIG_EXEC_PREFIX "\${prefix}")
set(PKG_CONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
set(PKG_CONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}")

and so can’t handle absolute paths in CMAKE_INSTALL_{INCLUDE,LIB}DIR. This leads to broken .pc files on NixOS in particular. (Deriving libdir from prefix rather than exec_prefix also seems a bit suspect, but is not the problem here.)

See “Concatenating paths when building pkg-config files” for a thorough discussion of the problem and a suggested fix, or KDE’s extra-cmake-modules for a simpler approach.

powercap-rapl: energy_uj file to be restricted to root access

Linux kernel development indicates that the energy_uj file will be restricted to root-only permissions [1] in an upcoming kernel release---probably 5.10.

The powercap-rapl interface currently only skips over files gracefully if they don't exist, but an open failure due to permissions will cause powercap_rapl_init to fail. We need to decide if, and if so, how, to address this file mode change.

The "default" approach is to not make any changes, which might be fine for most use cases. The powercap-rapl interface was primarily intended for software that needs to either read energy or change power caps with regularity, the latter of which already requires root access. Is it common to want to access other files that don't require root privileges with such regularity that using the powercap-rapl interface is desirable, as opposed to just using powercap-sysfs?

Because the kernel developers don't seem consider this an interface change (which IMO it is), any solution we implement should be general for all files in a zone (including constraint files), i.e., not limited to just working around energy_uj, in case other such kernel changes are made in the future.

[1] torvalds/linux@949dd01

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.