JetsonLeap is a framework that enables the design and test of energy-aware code transformations. It consists of an embedded hardware, a circuit to control the flow of energy, plus a library to instrument program parts.
We built an electrical circuit to enable or disable energy measurement by means of a signal fired from within the hardware under analysis. This signal sets the output port of a microcontroller to high or low level, enabling or disabling energy measurement.
When measurement is enabled, we use a power meter that captures voltage samples in real time. To process the output of the power measurement, a program is used to read the power produced at each sample and to generate a file with time and power values. We also compute the integral from these values in order to indicate numerically, in Joules, the energy consumed by the device.
For our experiments, we use an NVIDIA Jetson TK1 board, which contains a Tegra K1 system on a chip device, and runs Linux Ubuntu. For data acquisition, we are currently using a National Instruments 6009 DAQ and a interface implemented in C++ called CMeasure.
In order to send a signal to enable energy measurement, at first, the GPIO port must be enabled. Then, it is defined as output and finally, its logic level must be set. With our Jetson board, these procedures are performed by the following commands:
The first line enables the gpio165 port to be used; the second line defines the same port as output; and the third line defines the port logic level as high.
The library used in this project was implemented in C. Thus we wrote the commands above as C functions. Such functions are invoked from within the target program i.e., the program analyzed.
Below, there's an example of a function implemented to set the GPIO value and a target program that invokes this function in order to enable power measurement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int gpioSetValue (unsigned int gpio, unsigned int value) { int fileDescriptor; char commandBuffer[64]; snprintf(commandBuffer, sizeof(commandBuffer), "/sys/class/gpio/gpio%d/value", gpio); fileDescriptor = open(commandBuffer, 01); if (fileDescriptor < 0) { char errorBuffer[128] ; snprintf(errorBuffer,sizeof(errorBuffer), "gpioSetValue unable to open gpio%d",gpio) ; perror(errorBuffer); return fileDescriptor; } if (value && write(fileDescriptor, "1", 2) != 2) { perror("gpioSetValue"); return fileDescriptor; } else if (write(fileDescriptor, "0", 2) != 2) { perror("gpioSetValue"); return fileDescriptor; } close(fileDescriptor); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int main(int argc, char *argv[]) { // Do something without measuring energy // We are not measuring energy consumption // in foo(). foo(); // Start measuring energy: gpioSetValue(165, 1); // Do something measuring energy, e.g.: // Measure the energy consumed by bar(); bar(); // Stop measuring energy. gpioSetValue(165, 0); // Function baz() runs without energy // Measurement baz(); return 0; } |
Figure 1 shows a chart that we have produced with JetsonLeap, for a program that runs a sequential and a parallel version of mergesort. We have forced the program to sleep for 5 seconds in between each task, so that the beginning and ending of each phase is visually noticeable.
Figure 2 shows the components used to assemble the circuit: 01 resistor 0,1 ohm and 5W, 01 resistor 4,7K ohm and 0.25W, 01 transistor BC547, 01 relay 5V, 01 flyback diode, 04 bornes Metaltex, 01 Jack J4 with borne, 01 plug P4 with borne, and besides, 01 phenolite board, electronic welding, welding tin and iron perchlorate.
Figure 3 shows the equipment used to measure energy: the Jetson TK1 board, electric circuit that enables or disables the measurement of energy and the 6009 DAQ.
CMeasure is the interface that we use to get values with the National Instruments 6009 DAQ and to log them on an output file. The program was written in C++ and should be compiled with Visual Studio C++ 2010.