PowerSensor is a tool that measures the instantaneous power consumption of PCIe cards and SoC development boards like GPUs, Xeon Phis, FPGAs, DSPs, and network interfaces, at millisecond time scale. PowerSensor consists of a commodity microcontroller, commodity current sensors, and (for PCIe devices) a PCIe riser card. The microcontroller reports measurements to the host via USB. A small host library allows an application to determine its own energy efficiency. The high time resolution provides much better insights into energy usage than low-resolution built-in power meters (if available at all), as PowerSensor enables analysis of individual compute kernels.
PowerSensor is a tool that measures the instantaneous power consumption of PCIe cards and SoC development boards like GPUs, Xeon Phis, FPGAs, DSPs, and network cards, at sub-millisecond time scale. It consists of a commodity microcontroller, commodity current sensors, and (for PCIe devices) a PCIe riser card. The microcontroller reports measurements to the host via USB. A small host library allows an application to determine its own energy efficiency. The high time resolution (up to 8.62 kHz) provides much better insight into energy usage than low-resolution built-in power meters (if available at all), as PowerSensor enables analysis of individual compute kernels.
## Hardware
A PowerSensor measures the instantaneous power use of a GPU:
The PowerSensor hardware consists of an Arduino microcontroller board, current sensors (ACS712), a PCIe riser card (to measure the power drawn from the motherboard), an optional LCD screen, and a USB cable that connects to the host. In this typical scenario, we use three sensors that measure the PCIe slot power (12 V and 3.3 V) and the external PCIe cable power. The microcontroller interprets the readings from the current sensors, and reports the measured power consumption via USB to the host.
The PowerSensor consists of an Arduino Leonardo (or Arduino Pro Micro) board, current sensors (ACS712), a PCIe riser card (to measure the power drawn from the motherboard), an optional LCD screen, and a USB cable that connects to the host. In this scenario, we use three sensors that measure the PCIe slot power (12 V and 3.3 V) and the external PCIe cable power. The microcontroller interprets the sensor data and reports the power measurements via USB to the host.
PowerSensor gives insight into an application’s power efficiency:
<imgsrc="http://www.astron.nl/~romein/PowerSensor/graphs.png"alt="A few example graphs"width="60%">

This radio-astronomical pipeline filters, corrects, and correlates the signals from 960 receivers. The figure shows the instantaneous power consumption of three different devices. The correlation between energy use and executed kernels is clearly visible. The shaded area below the curve corresponds to the total energy used by a kernel.
## Disclaimer
...
...
@@ -29,7 +35,7 @@ Finally, connect the Arduino to a USB port of the host system. After making sur
## Installing the firmware
Make sure that the Arduino tools are installed on host system. On Ubuntu, one needs the `arduino-core` and `arduino-mk` packages. If necessary, adapt `Arduino/Makefile` to configure the right Arduino variant. The device typically appears as `/dev/ttyUSB0` or `/dev/ttyACM0` after it is connected to the host. Then, do `make upload` to build and install the firmware on the Arduino. The PowerSensor will not work properly until its is configured.
Make sure that the Arduino tools are installed on host system. On Ubuntu, one needs the `arduino-core` and `arduino-mk` packages. If necessary, adapt `Arduino/Makefile` to configure the right Arduino variant. The device typically appears as `/dev/ttyACM0` after it is connected to the host. Then, do `make upload` to build and install the firmware on the Arduino. The PowerSensor will not work properly until its is configured.
## Configuring the PowerSensor
...
...
@@ -42,38 +48,15 @@ PowerSensor supports up to 5 current sensors. All current sensor ports must be
`psconfig` accepts the parameters as described below. The order of parameters is important. Further on, we give examples of full configuration commands for a typical PowerSensor setup.
```
-h (--help):
print help message
-d dev (--device=dev):
arguments that follow apply to device dev. If -d is
not specified, /dev/ttyUSB0 is assumed.
-s N (--sensor=N):
arguments that follow apply to current sensor N. If -s
is not specified, current sensor 0 is assumed. Do not forget to configure
the other sensors though, or the device will not work.
-v N (--volt=N):
sets the voltage of the power line to be measured to N Volt.
-n N (--nulllevel=N):
sets the null level of the current sensor. N may also
be "auto"; in this case, it will use the currently measured level as null
level. This only works if there is no current flowing through the sensor.
-t type (--type=type):
sets the current sensor. Accepted values are
"ACS712-5", "ACS712-20", and "ACS712-30". For other types, use instead of
the type name a floating point number specifying the volt-per-ampere
sensitivity of the current sensor. This only works if the current sensor
outputs a voltage of 2.5V if no current is flowing.
-o (--off):
do not use this current sensor.
-p (--print):
print all configuration values and currently measured values.
The `-n` values may be adjusted to get the right null levels, depending on the local magnetic field. An easier way to calibrate them, is to fully turn of the host system power (so that no current is flowing through the current sensors), and to configure the PowerSensor from another machine (by temporarily connecting the USB cable to that other machine). In this case, the null levels can be configured automatically:
$ ./bin/x86_64/psconfig -d/dev/ttyACM0 -s0 -tACS712-20 -v12 -a -s1 -tACS712-5 -v3.3 -a -s2 -tACS712-20 -v12 -a -s3 -o -s4 -o -p
```
To see if the PowerSensor works correctly, one can use the `-p` option of `psconfig`, or use the `testPowerSensor` utility that appears in the `bin/arch` directory after invoking `make`.
## Testing the PowerSensor
To see if the PowerSensor works correctly, one can either use the `-p` option of `psconfig`:
```
$ ./bin/x86_64/psconfig -h
sensor: 0, volt: 12 V, type: ACS712-20, null level: -1.66026 W, current usage: 11.5142 W
sensor: 1, volt: 3.3 V, type: ACS712-5, null level: 0.0223578 W, current usage: 0.262142 W
sensor: 2, volt: 12 V, type: ACS712-20, null level: -1.75054 W, current usage: 11.19 W
sensor: 3, off
sensor: 4, off
```
Or use the `pstest` utility to measure and report energy consumption for a few seconds:
Adapting an application to use the library is not obligatory; the `psrun` utility can monitor the power use of a device during the execution of an application that does not use the library:
```
./bin/x86_64/pstest <application>
< application output >
24.0161 s, 5537,22 J, 230.563 W
```
## Using the host library
The host library is a small C++ library that can be used by applications to measure the power used by some (PCIe) device during some time interval. The interface (declared in `PowerSensor.h`) looks like this:
...
...
@@ -113,15 +134,18 @@ and can be used as follows:
```
#include <PowerSensor.h>
using namespace powersensor;
int main()
{
PowerSensor sensor("/dev/ttyUSB0");
PowerSensor sensor("/dev/ttyACM0");
PowerSensor::State start = sensor.read();
...
PowerSensor::State stop = sensor.read();
std::cout << "The computation took " << PowerSensor::Joules(start, stop) << 'J' << std::endl;
}
```
This way, the power consumption during some time interval can be used.
Another way to use the PowerSensor is to produce a stream of sensor values on file (in ASCII). Simply provide the name of the file as second (optional) argument to the constructor of PowerSensor. A separate, light-overhead thread will be started that continuously monitors the PowerSensor state. Both methods can be used at the same time.