RaplPowerMon.c 6.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <string.h>
//#include <asm/msr.h>

#define MSR_RAPL_POWER_UNIT             0x606

/*
 * Platform specific RAPL Domains.
 * Note that PP1 RAPL Domain is supported on 062A only
 * And DRAM RAPL Domain is supported on 062D only
 */
/* Package RAPL Domain */
#define MSR_PKG_RAPL_POWER_LIMIT        0x610
#define MSR_PKG_ENERGY_STATUS           0x611
#define MSR_PKG_PERF_STATUS             0x613
#define MSR_PKG_POWER_INFO              0x614

/* PP0 RAPL Domain */
#define MSR_PP0_POWER_LIMIT             0x638
#define MSR_PP0_ENERGY_STATUS           0x639
#define MSR_PP0_POLICY                  0x63A
#define MSR_PP0_PERF_STATUS             0x63B

/* PP1 RAPL Domain, may reflect to uncore devices */
#define MSR_PP1_POWER_LIMIT             0x640
#define MSR_PP1_ENERGY_STATUS           0x641
#define MSR_PP1_POLICY                  0x642

/* DRAM RAPL Domain */
#define MSR_DRAM_POWER_LIMIT            0x618
#define MSR_DRAM_ENERGY_STATUS          0x619
#define MSR_DRAM_PERF_STATUS            0x61B
#define MSR_DRAM_POWER_INFO             0x61C

/* RAPL UNIT BITMASK */
#define POWER_UNIT_OFFSET       0
#define POWER_UNIT_MASK         0x0F

#define ENERGY_UNIT_OFFSET      0x08
#define ENERGY_UNIT_MASK        0x1F00

#define TIME_UNIT_OFFSET        0x10
#define TIME_UNIT_MASK          0xF000
#define PKG_POWER_LIMIT_LOCK_OFFSET 0x3F
#define PKG_POWER_LIMIT_LOCK_MASK 0x1
#define ENABLE_LIMIT_2_OFFSET 0x2F

#define PKG_POWER_LIMIT_2_MASK 0x7FFF
#define ENABLE_LIMIT_1_OFFSET 0xF
#define ENABLE_LIMIT_1_MASK 0x1
#define PKG_CLAMPING_LIMIT_1_OFFSET 0x10
#define PKG_CLAMPING_LIMIT_1_MASK 0x1
#define PKG_POWER_LIMIT_1_OFFSET 0x0
#define PKG_POWER_LIMIT_1_MASK 0x7FFF
#define TIME_WINDOW_POWER_LIMIT_1_OFFSET 0x11
#define TIME_WINDOW_POWER_LIMIT_1_MASK 0x7F
#define TIME_WINDOW_POWER_LIMIT_2_OFFSET 0x31
#define TIME_WINDOW_POWER_LIMIT_2_MASK 0x7F


int open_msr(int core) {

  char msr_filename[BUFSIZ];
  int fd;

  sprintf(msr_filename, "/dev/cpu/%d/msr", core);
  fd = open(msr_filename, O_RDWR);
  if ( fd < 0 ) {
    if ( errno == ENXIO ) {
      fprintf(stderr, "rdmsr: No CPU %d\n", core);
      exit(2);
    } else if ( errno == EIO ) {
      fprintf(stderr, "rdmsr: CPU %d doesn't support MSRs\n", core);
      exit(3);
    } else {
      perror("rdmsr:open");
      fprintf(stderr,"Trying to open %s\n",msr_filename);
      exit(127);
    }
  }

  return fd;
}

long long read_msr(int fd, int which) {

  uint64_t data;

  if ( pread(fd, &data, sizeof data, which) != sizeof data ) {
    perror("rdmsr:pread");
    exit(127);
  }

  return (long long)data;
}

void write_msr(int fd, int which, uint64_t data) {

  if ( pwrite(fd, &data, sizeof data, which) != sizeof data ) {
    perror("wrmsr:pwrite");
    exit(127);
  }
}


int32_t wrmsr(int fd, uint64_t msr_number, uint64_t value)
{
        return pwrite(fd, (const void *)&value, sizeof(uint64_t), msr_number);
}

int32_t rdmsr(int fd, uint64_t msr_number, uint64_t * value)
{
        return pread(fd, (void *)value, sizeof(uint64_t), msr_number);
}

void set_power_limit(int fd, int watts, double pu)
{
/*
        uint32_t setpoint = (uint32_t) ((1 << pu) * watts);
        uint64_t reg = 0;
        rdmsr(fd, MSR_PKG_RAPL_POWER_LIMIT, &reg);
        reg = (reg & 0xFFFFFFFFFFFF0000) | setpoint | 0x8000;
        reg = (reg & 0xFFFFFFFF0000FFFF) | 0xD0000;
        wrmsr(fd, MSR_PKG_RAPL_POWER_LIMIT, reg);
*/

        uint32_t setpoint = (uint32_t) (watts/pu);
        uint64_t reg = 0;
        rdmsr(fd, MSR_PKG_RAPL_POWER_LIMIT, &reg);
        reg = (reg & 0xFFFFFFFFFFFF0000) | setpoint | 0x8000;
        reg = (reg & 0xFFFFFFFF0000FFFF) | 0xD0000;
        wrmsr(fd, MSR_PKG_RAPL_POWER_LIMIT, reg);



}


#define CPU_SANDYBRIDGE     42
#define CPU_SANDYBRIDGE_EP  45
#define CPU_IVYBRIDGE       58
#define CPU_IVYBRIDGE_EP    62



int main( int argc, char **argv ) {
  int fd1,fd2;
  long long result1, result2;
  double power_units,energy_units,time_units;
  double package1_before,package1_after,package2_before,package2_after;
  double pp0_before,pp0_after;
  double pp1_before=0.0,pp1_after;
  double dram_before=0.0,dram_after;
  double thermal_spec_power,minimum_power,maximum_power,time_window;
  int cpu_model;
  struct  timeval currentime1,currentime2,beginningtime;
  struct timespec interval_1s,interval_1ms,interval_10ms, interval_100ms, interval_500ms;
  long  double nowtime, power1, power2;
  float total_power;
 // char *filename;
  //char *W = "W";
  //FILE *file;
  gettimeofday(&beginningtime,NULL);
  interval_500ms.tv_sec = 0;
  interval_500ms.tv_nsec = 500000000;
  interval_100ms.tv_sec = 0;
  interval_100ms.tv_nsec = 100000000;
  interval_1s.tv_sec = 1;
  interval_1s.tv_nsec = 0;
  interval_1ms.tv_sec = 0;
  interval_1ms.tv_nsec = 1000000;
  interval_10ms.tv_sec = 0;
  interval_10ms.tv_nsec = 10000000;
  const char *powercap = argv[1];
  //char filename[20] = "PowerResultsOn";

 // strcat(filename, powercap);
 // strcat(filename, "W");
 // printf("filename = %s",filename);
//  file = fopen(filename,"a");
  fd1=open_msr(0);
  fd2=open_msr(10);

  /* Calculate the units used */
  result1=read_msr(fd1,MSR_RAPL_POWER_UNIT);

  power_units=pow(0.5,(double)(result1&0xf));
  energy_units=pow(0.5,(double)((result1>>8)&0x1f));
  time_units=pow(0.5,(double)((result1>>16)&0xf));

  uint64_t currentval, newval, mask = 0, offset = 0;
  currentval=read_msr(fd1,MSR_PKG_RAPL_POWER_LIMIT);
  currentval=read_msr(fd2,MSR_PKG_RAPL_POWER_LIMIT);
  int i;
  for (i= 0; i<1; i++){
        result1=read_msr(fd1,MSR_PKG_ENERGY_STATUS);
        result2=read_msr(fd2,MSR_PKG_ENERGY_STATUS);
        package1_before=(double)result1*energy_units;
        package2_before=(double)result2*energy_units;
        gettimeofday(&currentime1, NULL);

        //printf("\nSleeping 1 second\n\n");
        nanosleep(&interval_100ms, NULL);

        result1=read_msr(fd1,MSR_PKG_ENERGY_STATUS);
        result2=read_msr(fd2,MSR_PKG_ENERGY_STATUS);
        gettimeofday(&currentime2, NULL);



        package1_after=(double)result1*energy_units;

        package2_after=(double)result2*energy_units;

        nowtime =((long) ((currentime2.tv_usec - beginningtime.tv_usec) + (currentime2.tv_sec - beginningtime.tv_sec)* 1000000))/1000000.000000;
        power1 =((package1_after - package1_before) /((currentime2.tv_usec - currentime1.tv_usec) + (currentime2.tv_sec - currentime1.tv_sec)*1000000))*1000000;
        power2 =((package2_after - package2_before) /((currentime2.tv_usec - currentime1.tv_usec) + (currentime2.tv_sec - currentime1.tv_sec)*1000000))*1000000;
        //fprintf(file,"%LF %LF %LF\n", nowtime, power1, power2);
        total_power = (float)power1 +(float)power2;
        }



printf("%f\n", total_power);
return 1;
}