A Windows-only simplification of CPPJoules by rishalab — stripped down to 2 files, no CMake, no dependencies, plug-and-play with Visual Studio.
CPPJoules is a cross-platform C++ energy measurement library. This fork simplifies it for Windows developers who just want to measure CPU energy consumption without dealing with Linux RAPL paths, NVML, or a CMake build.
Drop cppJoules.h and cppJoules.cpp into your project and you're done.
| Requirement | Notes |
|---|---|
| Windows 11 (x64) | x86 not supported — Power Gadget is 64-bit only |
| Intel Power Gadget 3.6 | Installs EnergyLib64.dll into System32 |
| Visual Studio 2019 or later | C++17 or later |
Intel Power Gadget 3.6 installer is available in the original CPPJoules repo.
| Change | Detail |
|---|---|
| 7 files → 2 files | EnergyState, CPPJoulesException, RAPLDevice, EnergyTracker merged into cppJoules.h / cppJoules.cpp |
| Linux code removed | All /sys/class/powercap/ RAPL file reads, unistd.h, filesystem for Linux removed |
| macOS code removed | Apple framework path and dlfcn.h removed |
| NVML/Nvidia removed | nvidia_devices.h/.cpp and nvml.h dependency removed entirely |
LoadLibrary → LoadLibraryA |
Fixes Unicode mismatch in MSVC with char* path |
wchar_t narrowing fixed |
Replaced std::string(ws.begin(), ws.end()) with WideCharToMultiByte — fixes C4244 warning |
| Missing destructors added | ~RAPLDevice() calls FreeLibrary(), ~EnergyTracker() deletes RAPLDevice* — fixes resource leaks |
initialized typo fixed |
Original had #ifdef _W64 (wrong) instead of _WIN64 — flag was never set |
EXPOSE_DLL removed |
Pointless in a plain .exe, caused C4251 noise on all STL members |
EnergyState → value semantics |
Changed from vector<EnergyState*> with raw new to vector<EnergyState> |
Copy cppJoules.h and cppJoules.cpp into your project folder.
In Visual Studio: Add → Existing Item for both files.
Toolbar → change platform dropdown from x86 to x64.
Project Properties → C/C++ → Language → C++ Language Standard → ISO C++17
Intel Power Gadget requires elevated access to read MSR counters. Without it, all readings will be 0.
#include "cppJoules.h"
int main()
{
EnergyTracker tracker;
tracker.start();
// your code here
tracker.stop();
tracker.calculate_energy();
tracker.print_energy(); // prints mJ per domain to stdout
tracker.save_csv("results.csv"); // optional
return 0;
}Duration (s): 1.84
DRAM-0 : 4 mJ
IA-0 : 612 mJ
Processor-0 : 987 mJEnergy domains depend on your CPU. Common ones:
Processor-0— total package powerIA-0— CPU cores onlyDRAM-0— memory controller (not available on all laptop CPUs)GT-0— integrated GPU
EnergyTracker tracker; // loads EnergyLib64.dll, discovers power domains
tracker.start(); // records start timestamp + energy snapshot
tracker.stop(); // records stop timestamp + energy snapshot
tracker.calculate_energy(); // computes delta, resets state for reuse
tracker.print_energy(); // prints Duration + mJ per domain to stdout
tracker.save_csv("out.csv"); // writes results to CSV filecalculate_energy() resets the tracker state to UNINITIALIZED,
so start() can be called again for the next measurement.
| Symptom | Cause | Fix |
|---|---|---|
Could not load EnergyLib64.dll |
Power Gadget not installed | Install Intel Power Gadget 3.6 |
All readings are 0 mJ |
Not running as Administrator | Re-run with admin rights |
Build error on cppJoules.h |
Wrong include path | Confirm cppJoules.h is in the same folder or add its path to Additional Include Directories |
LNK2019 unresolved external |
cppJoules.cpp not in project |
Add via Add → Existing Item |