i7z-0.27.2/0000755000175000017500000000000012023752313010701 5ustar abhiabhii7z-0.27.2/MAKEDEV-cpuid-msr0000644000175000017500000000043012023553432013577 0ustar abhiabhi#!/bin/sh #this script is sourced from msr-tools package msr_major=202 cpuid_major=203 n=0 while [ $n -lt 32 ]; do mkdir -m 0755 -p /dev/cpu/$n mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n n=`expr $n + 1` done i7z-0.27.2/put_cores_online.sh0000644000175000017500000000050612023553432014606 0ustar abhiabhiecho 1 > /sys/devices/system/cpu/cpu1/online echo 1 > /sys/devices/system/cpu/cpu2/online echo 1 > /sys/devices/system/cpu/cpu3/online echo 1 > /sys/devices/system/cpu/cpu4/online echo 1 > /sys/devices/system/cpu/cpu5/online echo 1 > /sys/devices/system/cpu/cpu7/online sleep 30s echo 1 > /sys/devices/system/cpu/cpu6/online i7z-0.27.2/i7z.c0000644000175000017500000004664112023553432011572 0ustar abhiabhi//i7z.c /* ----------------------------------------------------------------------- * * * Copyright 2009 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include "getopt.h" #include "i7z.h" //#include "CPUHeirarchy.h" struct program_options prog_options; char* CPU_FREQUENCY_LOGGING_FILE_single="cpu_freq_log.txt"; char* CPU_FREQUENCY_LOGGING_FILE_dual="cpu_freq_log_dual_%d.txt"; char* CSTATE_LOGGING_FILE_single="cpu_cstate_log.txt"; char* CSTATE_LOGGING_FILE_dual="cpu_cstate_log_dual_%d.txt"; int Single_Socket(); int Dual_Socket(); int socket_0_num=0, socket_1_num=1; bool use_ncurses = true; /////////////////////LOGGING TO FILE//////////////////////////////////////// FILE *fp_log_file_freq; FILE *fp_log_file_freq_1, *fp_log_file_freq_2; FILE *fp_log_file_Cstates; FILE *fp_log_file_Cstates_1, *fp_log_file_Cstates_2; void logOpenFile_single() { if(prog_options.logging==1) { fp_log_file_freq = fopen(CPU_FREQUENCY_LOGGING_FILE_single,"w"); fp_log_file_Cstates = fopen(CSTATE_LOGGING_FILE_single,"w"); } else if(prog_options.logging==2) { fp_log_file_freq = fopen(CPU_FREQUENCY_LOGGING_FILE_single,"a"); fp_log_file_Cstates = fopen(CSTATE_LOGGING_FILE_single,"a"); } } void logCloseFile_single() { if(prog_options.logging!=0){ if(prog_options.logging==2) fprintf(fp_log_file_freq,"\n"); //the above line puts a \n after every freq is logged. fclose(fp_log_file_freq); fprintf(fp_log_file_Cstates,"\n"); //the above line puts a \n after every CSTATE is logged. fclose(fp_log_file_Cstates); } } // For dual socket make filename based on the socket number void logOpenFile_dual(int socket_num) { char str_file1[100]; snprintf(str_file1,100,CPU_FREQUENCY_LOGGING_FILE_dual,socket_num); char str_file2[100]; snprintf(str_file2,100,CSTATE_LOGGING_FILE_dual,socket_num); if(socket_num==0){ if(prog_options.logging==1) fp_log_file_freq_1 = fopen(str_file1,"w"); else if(prog_options.logging==2) fp_log_file_freq_1 = fopen(str_file1,"a"); } if(socket_num==1){ if(prog_options.logging==1) fp_log_file_freq_2 = fopen(str_file1,"w"); else if(prog_options.logging==2) fp_log_file_freq_2 = fopen(str_file1,"a"); } if(socket_num==0){ if(prog_options.logging==1) fp_log_file_Cstates_1 = fopen(str_file2,"w"); else if(prog_options.logging==2) fp_log_file_Cstates_1 = fopen(str_file2,"a"); } if(socket_num==1){ if(prog_options.logging==1) fp_log_file_Cstates_2 = fopen(str_file2,"w"); else if(prog_options.logging==2) fp_log_file_Cstates_2 = fopen(str_file2,"a"); } } void logCloseFile_dual(int socket_num) { if(socket_num==0){ if(prog_options.logging!=0){ if(prog_options.logging==2) fprintf(fp_log_file_freq_1,"\n"); //the above line puts a \n after every freq is logged. fclose(fp_log_file_freq_1); } } if(socket_num==1){ if(prog_options.logging!=0){ if(prog_options.logging==2) fprintf(fp_log_file_freq_2,"\n"); //the above line puts a \n after every freq is logged. fclose(fp_log_file_freq_2); } } if(socket_num==0){ if(prog_options.logging!=0){ if(prog_options.logging==2) fprintf(fp_log_file_Cstates_1,"\n"); //the above line puts a \n after every freq is logged. fclose(fp_log_file_Cstates_1); } } if(socket_num==1){ if(prog_options.logging!=0){ if(prog_options.logging==2) fprintf(fp_log_file_Cstates_2,"\n"); //the above line puts a \n after every freq is logged. fclose(fp_log_file_Cstates_2); } } } void logCpuFreq_single(float value) { //below when just logging if(prog_options.logging==1) { fprintf(fp_log_file_freq,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs } //below when appending if(prog_options.logging==2) { fprintf(fp_log_file_freq,"%f\t",value); } } void logCpuFreq_single_c(char* value) { //below when just logging if(prog_options.logging==1) { fprintf(fp_log_file_freq,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs } //below when appending if(prog_options.logging==2) { fprintf(fp_log_file_freq,"%s\t",value); } } void logCpuFreq_single_d(int value) { //below when just logging if(prog_options.logging==1) { fprintf(fp_log_file_freq,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs } //below when appending if(prog_options.logging==2) { fprintf(fp_log_file_freq,"%d\t",value); } } // fix for issue 48, suggested by Hakan void logCpuFreq_single_ts(struct timespec *value) //HW use timespec to avoid floating point overflow { //below when just logging if(prog_options.logging==1) { fprintf(fp_log_file_freq,"%d.%.9d\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs } //below when appending if(prog_options.logging==2) { fprintf(fp_log_file_freq,"%d.%.9d\t",value->tv_sec,value->tv_nsec); } } void logCpuFreq_dual(float value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_1,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_1,"%f\t",value); } if(socket_num==1){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_2,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_2,"%f\t",value); } } void logCpuFreq_dual_c(char* value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_1,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_1,"%s\t",value); } if(socket_num==1){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_2,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_2,"%s\t",value); } } void logCpuFreq_dual_d(int value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_1,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_1,"%d\t",value); } if(socket_num==1){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_2,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_2,"%d\t",value); } } void logCpuFreq_dual_ts(struct timespec *value, int socket_num) //HW use timespec to avoid floating point overflow { if(socket_num==0){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_1,"%d.%.9d\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_1,"%d.%.9d\t",value->tv_sec,value->tv_nsec); } if(socket_num==1){ //below when just logging if(prog_options.logging==1) fprintf(fp_log_file_freq_2,"%d.%.9d\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs //below when appending if(prog_options.logging==2) fprintf(fp_log_file_freq_2,"%d.%.9d\t",value->tv_sec,value->tv_nsec); } } void logCpuCstates_single(float value) { //below when just logging if(prog_options.logging != 0) { fprintf(fp_log_file_Cstates,"%f",value); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_single_c(char* value) { //below when just logging if(prog_options.logging != 0) { fprintf(fp_log_file_Cstates,"%s",value); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_single_d(int value) { //below when just logging if(prog_options.logging != 0) { fprintf(fp_log_file_Cstates,"%d",value); //newline, replace \n with \t to get everything separated with tabs } } // fix for issue 48, suggested by Hakan void logCpuCstates_single_ts(struct timespec *value) //HW use timespec to avoid floating point overflow { //below when just logging if(prog_options.logging != 0) { fprintf(fp_log_file_Cstates,"%d.%.9d",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_dual(float value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_1,"%f",value); //newline, replace \n with \t to get everything separated with tabs } if(socket_num==1){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_2,"%f",value); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_dual_c(char* value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_1,"%s",value); //newline, replace \n with \t to get everything separated with tabs } if(socket_num==1){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_2,"%s",value); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_dual_d(int value,int socket_num) { if(socket_num==0){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_1,"%d",value); //newline, replace \n with \t to get everything separated with tabs } if(socket_num==1){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_2,"%d",value); //newline, replace \n with \t to get everything separated with tabs } } void logCpuCstates_dual_ts(struct timespec *value, int socket_num) //HW use timespec to avoid floating point overflow { if(socket_num==0){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_1,"%d.%.9d",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs } if(socket_num==1){ //below when just logging if(prog_options.logging != 0) fprintf(fp_log_file_Cstates_2,"%d.%.9d",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs } } void atexit_runsttysane() { printf("Quitting i7z\n"); system("stty sane"); } void modprobing_msr() { system("modprobe msr"); } //Info: I start from index 1 when i talk about cores on CPU #define MAX_FILENAME_LENGTH 1000 int main (int argc, char **argv) { atexit(atexit_runsttysane); char log_file_name[MAX_FILENAME_LENGTH], log_file_name2[MAX_FILENAME_LENGTH+3]; prog_options.logging=0; //0=no logging, 1=logging, 2=appending struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; //////////////////// GET ARGUMENTS ////////////////////// int c; //char *cvalue = NULL; //static bool logging_val_append=false, logging_val_replace=false; bool presupplied_socket_info = false; static struct option long_options[]= { {"write", required_argument, 0, 'w'}, {"socket0", required_argument,0 ,'z'}, {"socket1", required_argument,0 ,'y'}, {"logfile", required_argument,0,'l'}, {"help", no_argument, 0, 'h'}, {"nogui", no_argument, 0, 'n'} }; prog_options.logging = 0; while(1) { int option_index = 0; c = getopt_long(argc, argv,"w:z:y:l:hn", long_options, &option_index); if (c==-1) break; switch(c) { case 'z': socket_0_num = atoi(optarg); presupplied_socket_info = true; printf("Socket_0 information will be about socket %d\n", socket_0.socket_num); break; case 'y': socket_1_num = atoi(optarg); presupplied_socket_info = true; printf("Socket_1 information will be about socket %d\n", socket_1.socket_num); break; case 'w': //printf("write options specified %s\n", optarg); if (strcmp("l",optarg)==0) { prog_options.logging = 1; printf("Logging is ON and set to replace\n"); } if (strcmp("a",optarg)==0) { prog_options.logging = 2; printf("Logging is ON and set to append\n"); } break; case 'l': strncpy(log_file_name, optarg, MAX_FILENAME_LENGTH-3); strcpy(log_file_name2, log_file_name); strcat(log_file_name2, "_%d"); CPU_FREQUENCY_LOGGING_FILE_single = log_file_name; CPU_FREQUENCY_LOGGING_FILE_dual = log_file_name2; printf("Logging frequencies to %s for single sockets, %s for dual sockets(0,1 for multiple sockets)\n", CPU_FREQUENCY_LOGGING_FILE_single, CPU_FREQUENCY_LOGGING_FILE_dual); break; case 'n': use_ncurses = false; printf("Not Spawning the GUI\n"); break; case 'h': printf("\ni7z Tool Supports the following functions:\n"); printf("Append to a log file: "); printf("%c[%d;%d;%dm./i7z --write a ", 0x1B,1,31,40); printf("%c[%dm[OR] ",0x1B,0); printf("%c[%d;%d;%dm./i7z -w a\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Replacement instead of Append: "); printf("%c[%d;%d;%dm./i7z --write l ", 0x1B,1,31,40); printf("%c[%dm[OR]", 0x1B,0); printf(" %c[%d;%d;%dm./i7z -w l\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Default log file name is %s (single socket) or %s (dual socket)\n", CPU_FREQUENCY_LOGGING_FILE_single, CPU_FREQUENCY_LOGGING_FILE_dual); printf("Specifying a different log file: "); printf("%c[%d;%d;%dm./i7z --logfile filename ", 0x1B,1,31,40); printf("%c[%dm[OR] ", 0x1B,0); printf("%c[%d;%d;%dm./i7z -l filename\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Specifying a particular socket to print: %c[%d;%d;%dm./i7z --socket0 X \n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("In order to print to a second socket use: %c[%d;%d;%dm./i7z --socket1 X \n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("To turn the ncurses GUI off use: %c[%d;%d;%dm./i7z --nogui\n", 0x1B, 1, 31, 40); printf("%c[%dm",0x1B,0); printf("Example: To print for two sockets and also change the log file %c[%d;%d;%dm./i7z --socket0 0 --socket1 1 -logfile /tmp/logfilei7z -w l\n", 0x1B, 1, 31, 40); printf("%c[%dm",0x1B,0); exit(1); break; } } Print_Version_Information(); Print_Information_Processor (&prog_options.i7_version.nehalem, &prog_options.i7_version.sandy_bridge); // printf("nehalem %d, sandy brdige %d\n", prog_options.i7_version.nehalem, prog_options.i7_version.sandy_bridge); Test_Or_Make_MSR_DEVICE_FILES (); modprobing_msr(); /* prog_options.logging = 0; if (logging_val_replace){ prog_options.logging = 1; printf("Logging is ON and set to replace\n"); } if (logging_val_append){ prog_options.logging = 2; printf("Logging is ON and set to append\n"); } */ /* while( (c=getopt(argc,argv,"w:")) !=-1){ cvalue = optarg; //printf("argument %c\n",c); if(cvalue == NULL){ printf("With -w option, requires an argument for append or logging\n"); exit(1); }else{ //printf(" %s\n",cvalue); if(strcmp(cvalue,"a")==0){ printf("Appending frequencies to %s (single_socket) or cpu_freq_log_dual_(%d/%d).txt (dual socket)\n", CPU_FREQUENCY_LOGGING_FILE_single,0,1); prog_options.logging=2; }else if(strcmp(cvalue,"l")==0){ printf("Logging frequencies to %s (single socket) or cpu_freq_log_dual_(%d/%d).txt (dual socket) \n", CPU_FREQUENCY_LOGGING_FILE_single,0,1); prog_options.logging=1; }else{ printf("Unknown Option, ignoring -w option.\n"); prog_options.logging=0; } sleep(3); } } */ /////////////////////////////////////////////////////////// construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); print_socket_information(&socket_0); print_socket_information(&socket_1); if (!use_ncurses){ printf("GUI has been Turned OFF\n"); if (prog_options.logging ==0) { printf("Logging is OFF\n"); } else { printf("Logging is ON\n"); } } else { printf("GUI has been Turned ON\n"); if (prog_options.logging ==0) { printf("Logging is OFF\n"); } else { printf("Logging is ON\n"); } } if (!presupplied_socket_info){ if (socket_0.max_cpu>0 && socket_1.max_cpu>0) { //Path for Dual Socket Code printf("i7z DEBUG: Dual Socket Detected\n"); //Dual_Socket(&prog_options); Dual_Socket(); } else { //Path for Single Socket Code printf("i7z DEBUG: Single Socket Detected\n"); //Single_Socket(&prog_options); Single_Socket(); } } else { Dual_Socket(); } return(1); } i7z-0.27.2/i7z.h0000644000175000017500000001227712023553432011575 0ustar abhiabhi//i7z.h /* ----------------------------------------------------------------------- * * * Copyright 2009 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ #include #define i7z_VERSION_INFO "svn-r77-(20-Nov-2011)" //structure to store the information about the processor #define proccpuinfo "/proc/cpuinfo" #ifndef bool #define bool int #endif #define false 0 #define true 1 #define MAX_PROCESSORS 128 #define MAX_HI_PROCESSORS MAX_PROCESSORS #define MAX_SK_PROCESSORS (MAX_PROCESSORS/4) //add newer version of core processors here, this is basically to change any things that are done to the register //seems like sandybridge doesnot use the IA32_TEMPERATURE_TARGET in Read_Thermal_Status_CPU struct core_i7_version{ bool nehalem; bool sandy_bridge; }; struct program_options{ int logging; //0=no logging, 1=logging, 2=appending struct core_i7_version i7_version; }; /// Logging Functions void logOpenFile_single(); void logCloseFile_single(); void logCpuFreq_single(float value); void logOpenFile_dual(int); void logCloseFile_dual(int); void logCpuFreq_dual(float,int); void logCpuFreq_dual_d(int, int); void logCpuFreq_dual_ts(struct timespec *value, int) ; void logCpuCstates_single(float value); void logCpuCstates_single_c(char* value); //void logCpuCstates_single_d(int value); void logCpuCstates_single_ts(struct timespec *value) ; void logCpuCstates_dual(float value, int); void logCpuCstates_dual_c(char* value, int); void logCpuCstates_dual_ts(struct timespec *value, int) ; struct cpu_heirarchy_info { int max_online_cpu; int num_sockets; int sibling_num[MAX_HI_PROCESSORS]; int processor_num[MAX_HI_PROCESSORS]; int package_num[MAX_HI_PROCESSORS]; int coreid_num[MAX_HI_PROCESSORS]; int display_cores[MAX_HI_PROCESSORS]; bool HT; }; struct cpu_socket_info { int max_cpu; int socket_num; int processor_num[MAX_SK_PROCESSORS]; int num_physical_cores; int num_logical_cores; }; struct family_info { char stepping; char model; char family; char processor_type; char extended_model; int extended_family; }; //read TSC() code for 32 and 64-bit //http://www.mcs.anl.gov/~kazutomo/rdtsc.html #ifndef x64_BIT //code for 32 bit static __inline__ unsigned long long int rdtsc () { unsigned long long int x; __asm__ volatile (".byte 0x0f, 0x31":"=A" (x)); return x; } #endif #ifdef x64_BIT //code for 32 bit static __inline__ unsigned long long rdtsc (void) { unsigned hi, lo; __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); } #endif void print_family_info (struct family_info *proc_info); //void get_vendor (char *vendor_string); int turbo_status (); double cpufreq_info(); //void get_familyinformation (struct family_info *proc_info); double estimate_MHz (); uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, unsigned int lowbit, int* error_indx); uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data); #ifdef USE_INTEL_CPUID void get_CPUs_info (unsigned int *num_Logical_OS, unsigned int *num_Logical_process, unsigned int *num_Processor_Core, unsigned int *num_Physical_Socket); #endif int get_number_of_present_cpu(); void get_candidate_cores(struct cpu_heirarchy_info* chi); void get_online_cpus(struct cpu_heirarchy_info* chi); void get_siblings_list(struct cpu_heirarchy_info* chi); void get_package_ids(struct cpu_heirarchy_info* chi); void print_cpu_list(struct cpu_heirarchy_info chi); void construct_cpu_hierarchy(struct cpu_heirarchy_info *chi); void Print_Information_Processor(bool*, bool*); void Test_Or_Make_MSR_DEVICE_FILES(); int check_and_return_processor(char*strinfo); int check_and_return_physical_id(char*strinfo); void construct_sibling_list(struct cpu_heirarchy_info* chi); void construct_socket_information(struct cpu_heirarchy_info* chi, struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1, int, int); void print_socket_information(struct cpu_socket_info* socket); void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi); void print_CPU_Heirarchy(struct cpu_heirarchy_info chi); int in_core_list(int ii,int* core_list); void Print_Version_Information(); bool file_exists(char*); #define SET_ONLINE_ARRAY_MINUS1(online_cpus) {int iii;for(iii=0;iii100, the below macro checks till 101 #define THRESHOLD_BETWEEN_0_100(cond) (cond>=-1 && cond <=125 && !isinf(cond) && !isnan(cond))? cond: __builtin_inf() //due to the fact that sometimes 100.0>100, the below macro checks till 101 #define IS_THIS_BETWEEN_0_100(cond) (cond>=-1 && cond <=125 && !isinf(cond) && !isnan(cond))? 0: 1 #define THRESHOLD_BETWEEN_0_6000(cond) (cond>=0 && cond <=10000)? cond: __builtin_inf() i7z-0.27.2/put_cores_offline.sh0000644000175000017500000000050612023553432014744 0ustar abhiabhiecho 0 > /sys/devices/system/cpu/cpu1/online echo 0 > /sys/devices/system/cpu/cpu2/online echo 0 > /sys/devices/system/cpu/cpu3/online echo 0 > /sys/devices/system/cpu/cpu4/online echo 0 > /sys/devices/system/cpu/cpu5/online echo 0 > /sys/devices/system/cpu/cpu7/online sleep 30s echo 0 > /sys/devices/system/cpu/cpu6/online i7z-0.27.2/i7z_Dual_Socket.c0000644000175000017500000010215312023553432014036 0ustar abhiabhi//i7z_Dual_Socket.c /* ----------------------------------------------------------------------- * * * Copyright 2010 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "i7z.h" #define U_L_I unsigned long int #define U_L_L_I unsigned long long int #define numCPUs_max MAX_PROCESSORS extern int socket_0_num, socket_1_num; extern bool E7_mp_present; extern int numPhysicalCores, numLogicalCores; extern double TRUE_CPU_FREQ; int Read_Thermal_Status_CPU(int cpu_num); extern struct program_options prog_options; FILE *fp_log_file; struct timespec global_ts; extern FILE *fp_log_file_freq_1, *fp_log_file_freq_2; extern char* CPU_FREQUENCY_LOGGING_FILE_single; extern char* CPU_FREQUENCY_LOGGING_FILE_dual; extern bool use_ncurses; void print_i7z (); int Dual_Socket () { //zero up the file before doing anything if(prog_options.logging!=0){ char str_file[100]; snprintf(str_file,100,CPU_FREQUENCY_LOGGING_FILE_dual,0); fp_log_file = fopen(str_file,"w"); fclose(fp_log_file); snprintf(str_file,100,CPU_FREQUENCY_LOGGING_FILE_dual,1); fp_log_file = fopen(str_file,"w"); fclose(fp_log_file); } //int row, col; /* to store the number of rows and * * the number of colums of the screen * * for NCURSES */ printf ("i7z DEBUG: In i7z Dual_Socket()\n"); sleep (3); if (use_ncurses) { //Setup stuff for ncurses initscr (); /* start the curses mode */ start_color (); //getmaxyx (stdscr, row, col); /* get the number of rows and columns */ refresh (); //Setup for ncurses completed } print_i7z(); exit (0); return (1); } void print_i7z_socket(struct cpu_socket_info socket_0, int printw_offset, int PLATFORM_INFO_MSR, int PLATFORM_INFO_MSR_high, int PLATFORM_INFO_MSR_low, int* online_cpus, double cpu_freq_cpuinfo, struct timespec one_second_sleep, char TURBO_MODE, char* HT_ON_str, int* kk_1, U_L_L_I * old_val_CORE, U_L_L_I * old_val_REF, U_L_L_I * old_val_C3, U_L_L_I * old_val_C6, U_L_L_I* old_val_C7, U_L_L_I * old_TSC, int estimated_mhz, U_L_L_I * new_val_CORE, U_L_L_I * new_val_REF, U_L_L_I * new_val_C3, U_L_L_I * new_val_C6, U_L_L_I* new_val_C7, U_L_L_I * new_TSC, double* _FREQ, double* _MULT, long double * C0_time, long double * C1_time, long double * C3_time, long double * C6_time, long double* C7_time, struct timeval* tvstart, struct timeval* tvstop, int *max_observed_cpu) { int numPhysicalCores=0, numLogicalCores=0; double TRUE_CPU_FREQ; int i, ii; //int k; int CPU_NUM; int* core_list; unsigned long int IA32_MPERF, IA32_APERF; int CPU_Multiplier, error_indx; unsigned long long int CPU_CLK_UNHALTED_CORE, CPU_CLK_UNHALTED_REF, CPU_CLK_C3, CPU_CLK_C6, CPU_CLK_C1, CPU_CLK_C7; char print_core[32]; //current blck value float BLCK; long double c1_time; //use this variable to monitor the max number of cores ever online *max_observed_cpu = (socket_0.max_cpu > *max_observed_cpu)? socket_0.max_cpu: *max_observed_cpu; int core_list_size_phy, core_list_size_log; if (socket_0.max_cpu > 0) { //set the variable print_core to 0, use it to check if a core is online and doesnt //have any garbage values memset(print_core, 0, 6*sizeof(char)); //We just need one CPU (we use Core-1) to figure out the multiplier and the bus clock freq. //multiplier doesnt automatically include turbo //note turbo is not guaranteed, only promised //So this msr will only reflect the actual multiplier, rest has to be figured out //Now get all the information about the socket from the structure CPU_NUM = socket_0.processor_num[0]; core_list = socket_0.processor_num; core_list_size_phy = socket_0.num_physical_cores; core_list_size_log = socket_0.num_logical_cores; /*if (CPU_NUM == -1) { sleep (1); //sleep for a bit hoping that the offline socket becomes online continue; }*/ //number of CPUs is as told via cpuinfo int numCPUs = socket_0.num_physical_cores; CPU_Multiplier = get_msr_value (CPU_NUM, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Blck is basically the true speed divided by the multiplier BLCK = cpu_freq_cpuinfo / CPU_Multiplier; //Use Core-1 as the one to check for the turbo limit //Core number shouldnt matter //bits from 0-63 in this store the various maximum turbo limits int MSR_TURBO_RATIO_LIMIT = 429; // 3B defines till Max 4 Core and the rest bit values from 32:63 were reserved. int MAX_TURBO_1C=0, MAX_TURBO_2C=0, MAX_TURBO_3C=0, MAX_TURBO_4C=0, MAX_TURBO_5C=0, MAX_TURBO_6C=0; if (E7_mp_present){ // e7-mps dont have the 429 register! } else { //Bits:0-7 - core1 MAX_TURBO_1C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:15-8 - core2 MAX_TURBO_2C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 15, 8, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:23-16 - core3 MAX_TURBO_3C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 23, 16, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:31-24 - core4 MAX_TURBO_4C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 31, 24, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //gulftown/Hexacore support //technically these should be the bits to get for core 5,6 //Bits:39-32 - core4 MAX_TURBO_5C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 39, 32, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:47-40 - core4 MAX_TURBO_6C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 47, 40, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); } //fflush (stdout); //sleep (1); char string_ptr1[200], string_ptr2[200]; int IA32_PERF_GLOBAL_CTRL = 911; //38F int IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); int IA32_FIXED_CTR_CTL = 909; //38D int IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); CPU_CLK_UNHALTED_CORE = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); CPU_CLK_UNHALTED_REF = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); //SLEEP FOR 1 SECOND (500ms is also alright) nanosleep (&one_second_sleep, NULL); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx) - IA32_MPERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx) - IA32_APERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); mvprintw (4 + printw_offset, 0," CPU Multiplier %dx || Bus clock frequency (BCLK) %0.2f MHz \n", CPU_Multiplier, BLCK); if (numCPUs <= 0) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 0 cores is"); sprintf (string_ptr2, " "); } if (numCPUs >= 1 && numCPUs < 4) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2 cores is"); sprintf (string_ptr2, " %dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C); } if (numCPUs >= 2 && numCPUs < 6) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2/3/4 cores is"); sprintf (string_ptr2, " %dx/%dx/%dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C, MAX_TURBO_3C, MAX_TURBO_4C); } if (numCPUs >= 2 && numCPUs >= 6) // Gulftown 6-cores, Nehalem-EX { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2/3/4/5/6 cores is"); sprintf (string_ptr2, " %dx/%dx/%dx/%dx/%dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C, MAX_TURBO_3C, MAX_TURBO_4C, MAX_TURBO_5C, MAX_TURBO_6C); } if (socket_0.socket_num == 0) { mvprintw (31, 0, "C0 = Processor running without halting"); mvprintw (32, 0, "C1 = Processor running with halts (States >C0 are power saver)"); mvprintw (33, 0, "C3 = Cores running with PLL turned off and core cache turned off"); mvprintw (34, 0, "C6 = Everything in C3 + core state saved to last level cache"); mvprintw (35, 0, " Above values in table are in percentage over the last 1 sec"); mvprintw (36, 0, "[core-id] refers to core-id number in /proc/cpuinfo"); mvprintw (37, 0, "'Garbage Values' message printed when garbage values are read"); mvprintw (38, 0, " Ctrl+C to exit"); } numCPUs = core_list_size_phy; numPhysicalCores = core_list_size_phy; numLogicalCores = core_list_size_log; mvprintw (3 + printw_offset, 0, "Socket [%d] - [physical cores=%d, logical cores=%d, max online cores ever=%d] \n", socket_0.socket_num, numPhysicalCores, numLogicalCores,*max_observed_cpu); mvprintw (7 + printw_offset, 0, "%s %s\n", string_ptr1, string_ptr2); if (TURBO_MODE == 1) { mvprintw (5 + printw_offset, 0, " TURBO ENABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier + 1); mvprintw (6 + printw_offset, 0, " Max Frequency without considering Turbo %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier + 1); } else { mvprintw (5 + printw_offset, 0, " TURBO DISABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier); mvprintw (6 + printw_offset, 0," Max Frequency without considering Turbo %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier); } //Primarily for 32-bit users, found that after sometimes the counters loopback, so inorder //to prevent loopback, reset the counters back to 0 after 10 iterations roughly 10 secs if (*kk_1 > 10) { *kk_1 = 0; for (i = 0; i < numCPUs; i++) { //Set up the performance counters and then start reading from them assert(i < MAX_SK_PROCESSORS); CPU_NUM = core_list[i]; ii = core_list[i]; assert(i < MAX_PROCESSORS); //online_cpus[i] assert(ii < numCPUs_max); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); set_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 0x700000003LLU); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); set_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 819); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); if (prog_options.i7_version.sandy_bridge){ old_val_C7[ii] = get_msr_value (CPU_NUM, 1022, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); } old_TSC[ii] = rdtsc (); } } (*kk_1)++; nanosleep (&one_second_sleep, NULL); if (prog_options.i7_version.sandy_bridge){ mvprintw (9 + printw_offset, 0, "\tCore [core-id] :Actual Freq (Mult.)\t C0%% Halt(C1)%% C3 %% C6 %% C7 %% Temp\n"); }else{ mvprintw (9 + printw_offset, 0, "\tCore [core-id] :Actual Freq (Mult.)\t C0%% Halt(C1)%% C3 %% C6 %% Temp\n"); } //estimate the CPU speed estimated_mhz = estimate_MHz (); for (i = 0; i < numCPUs; i++) { //read from the performance counters //things like halted unhalted core cycles assert(i < MAX_SK_PROCESSORS); CPU_NUM = core_list[i]; ii = core_list[i]; assert(i < MAX_PROCESSORS); //online_cpus[i] assert(ii < numCPUs_max); new_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); if (prog_options.i7_version.sandy_bridge) { new_val_C7[ii] = get_msr_value (CPU_NUM, 1022, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); } new_TSC[ii] = rdtsc (); if (old_val_CORE[ii] > new_val_CORE[ii]) { //handle overflow CPU_CLK_UNHALTED_CORE = (UINT64_MAX - old_val_CORE[ii]) + new_val_CORE[ii]; } else { CPU_CLK_UNHALTED_CORE = new_val_CORE[ii] - old_val_CORE[ii]; } //number of TSC cycles while its in halted state if ((new_TSC[ii] - old_TSC[ii]) < CPU_CLK_UNHALTED_CORE) { CPU_CLK_C1 = 0; } else { CPU_CLK_C1 = ((new_TSC[ii] - old_TSC[ii]) - CPU_CLK_UNHALTED_CORE); } if (old_val_REF[ii] > new_val_REF[ii]) { //handle overflow CPU_CLK_UNHALTED_REF = (UINT64_MAX - old_val_REF[ii]) + new_val_REF[ii]; //3.40282366921e38 } else { CPU_CLK_UNHALTED_REF = new_val_REF[ii] - old_val_REF[ii]; } if (old_val_C3[ii] > new_val_C3[ii]) { //handle overflow CPU_CLK_C3 = (UINT64_MAX - old_val_C3[ii]) + new_val_C3[ii]; } else { CPU_CLK_C3 = new_val_C3[ii] - old_val_C3[ii]; } if (old_val_C6[ii] > new_val_C6[ii]) { //handle overflow CPU_CLK_C6 = (UINT64_MAX - old_val_C6[ii]) + new_val_C6[ii]; } else { CPU_CLK_C6 = new_val_C6[ii] - old_val_C6[ii]; } if(prog_options.i7_version.sandy_bridge) { if (old_val_C7[ii] > new_val_C7[ii]) { //handle overflow CPU_CLK_C7 = (UINT64_MAX - old_val_C7[ii]) + new_val_C7[ii]; } else { CPU_CLK_C7 = new_val_C7[ii] - old_val_C7[ii]; } } _FREQ[ii] = THRESHOLD_BETWEEN_0_6000(estimated_mhz * ((long double) CPU_CLK_UNHALTED_CORE / (long double) CPU_CLK_UNHALTED_REF)); _MULT[ii] = _FREQ[ii] / BLCK; C0_time[ii] = ((long double) CPU_CLK_UNHALTED_REF / (long double) (new_TSC[ii] - old_TSC[ii])); C1_time[ii] = ((long double) CPU_CLK_C1 / (long double) (new_TSC[ii] - old_TSC[ii])); C3_time[ii] = ((long double) CPU_CLK_C3 / (long double) (new_TSC[ii] - old_TSC[ii])); C6_time[ii] = ((long double) CPU_CLK_C6 / (long double) (new_TSC[ii] - old_TSC[ii])); if(prog_options.i7_version.sandy_bridge) { C7_time[ii] = ((long double) CPU_CLK_C7 / (long double) (new_TSC[ii] - old_TSC[ii])); } if (C0_time[ii] < 1e-2) { if (C0_time[ii] > 1e-4) { C0_time[ii] = 0.01; } else { C0_time[ii] = 0; } } if (C1_time[ii] < 1e-2) { if (C1_time[ii] > 1e-4) { C1_time[ii] = 0.01; } else { C1_time[ii] = 0; } } if (C3_time[ii] < 1e-2) { if (C3_time[ii] > 1e-4) { C3_time[ii] = 0.01; } else { C3_time[ii] = 0; } } if (C6_time[ii] < 1e-2) { if (C6_time[ii] > 1e-4) { C6_time[ii] = 0.01; } else { C6_time[ii] = 0; } } if (prog_options.i7_version.sandy_bridge) { if (C7_time[ii] < 1e-2) { if (C7_time[ii] > 1e-4) { C7_time[ii] = 0.01; } else { C7_time[ii] = 0; } } } } //CHECK IF ALL COUNTERS ARE CORRECT AND NO GARBAGE VALUES ARE PRESENT //If there is any garbage values set print_core[i] to 0 for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if (prog_options.i7_version.sandy_bridge) { if ( !IS_THIS_BETWEEN_0_100(C0_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100) || !IS_THIS_BETWEEN_0_100(C3_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C6_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C7_time[i] * 100) || isinf(_FREQ[i]) ) print_core[ii]=0; else print_core[ii]=1; } else { if ( !IS_THIS_BETWEEN_0_100(C0_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100) || !IS_THIS_BETWEEN_0_100(C3_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C6_time[i] * 100) || isinf(_FREQ[i]) ) print_core[ii]=0; else print_core[ii]=1; } } //Now print the information about the cores. Print garbage values message if there is garbage for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if (prog_options.i7_version.sandy_bridge) { //there is a bit of leeway to be had as the counts might be off by a bit //thus threshold so that the diff is thresholded to 0 c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i] + C7_time[i]) * 100; if ( !isnan(c1_time) && !isinf(c1_time)) { if (c1_time<=0) { c1_time=0; } } if (print_core[ii]) mvprintw (10 + ii + printw_offset, 0, "\tCore %d [%d]:\t %0.2f (%.2fx)\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%d\n", ii + 1, core_list[ii], _FREQ[i], _MULT[i], THRESHOLD_BETWEEN_0_100(C0_time[i] * 100), THRESHOLD_BETWEEN_0_100(c1_time), THRESHOLD_BETWEEN_0_100(C3_time[i] * 100), THRESHOLD_BETWEEN_0_100(C6_time[i] * 100), THRESHOLD_BETWEEN_0_100(C7_time[i] * 100), Read_Thermal_Status_CPU(core_list[ii])); //C0_time[i]*100+C1_time[i]*100 around 100 else mvprintw (10 + ii + printw_offset, 0, "\tCore %d [%d]:\t Garbage Values\n", ii + 1, core_list[ii]); } else { //there is a bit of leeway to be had as the counts might be off by a bit //thus threshold so that the diff is thresholded to 0 c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100; if ( !isnan(c1_time) && !isinf(c1_time)) { if (c1_time<=0) { c1_time=0; } } if (print_core[ii]) mvprintw (10 + ii + printw_offset, 0, "\tCore %d [%d]:\t %0.2f (%.2fx)\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%d\n", ii + 1, core_list[ii], _FREQ[i], _MULT[i], THRESHOLD_BETWEEN_0_100(C0_time[i] * 100), THRESHOLD_BETWEEN_0_100(c1_time), THRESHOLD_BETWEEN_0_100(C3_time[i] * 100), THRESHOLD_BETWEEN_0_100(C6_time[i] * 100),Read_Thermal_Status_CPU(core_list[ii])); //C0_time[i]*100+C1_time[i]*100 around 100 else mvprintw (10 + ii + printw_offset, 0, "\tCore %d [%d]:\t Garbage Values\n", ii + 1, core_list[ii]); } } /*k=0; for (ii = 00; ii < *max_observed_cpu; ii++) { if (in_core_list(ii,core_list)){ continue; }else{ mvprintw (10 + k + numCPUs + printw_offset, 0, "\tProcessor %d [%d]: OFFLINE\n", k + numCPUs + 1, ii); } k++; }*/ //FOR THE REST OF THE CORES (i.e. the offline cores+non-present cores=6 ) //I have space allocated for 6 cores to be printed per socket so from all the present cores //till 6 print a blank line //for(ii=*max_observed_cpu; ii<6; ii++) for (ii = numCPUs ; ii<6; ii++) mvprintw (10 + ii + printw_offset, 0, "\n"); TRUE_CPU_FREQ = 0; logOpenFile_dual(socket_0.socket_num); clock_gettime(CLOCK_REALTIME, &global_ts); logCpuFreq_dual_ts(&global_ts, socket_0.socket_num); logCpuCstates_dual_ts(&global_ts, socket_0.socket_num); for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if ( (_FREQ[i] > TRUE_CPU_FREQ) && (print_core[ii]) && !isinf(_FREQ[i]) ) { TRUE_CPU_FREQ = _FREQ[i]; } if ( (print_core[ii]) && !isinf(_FREQ[i]) ) { logCpuFreq_dual(_FREQ[i],socket_0.socket_num); } logCpuCstates_dual_c(" [",socket_0.socket_num); logCpuCstates_dual((float)THRESHOLD_BETWEEN_0_100(C0_time[i] * 100),socket_0.socket_num); logCpuCstates_dual_c(",",socket_0.socket_num); //c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i] + C7_time[i]) * 100; c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100; logCpuCstates_dual((float)THRESHOLD_BETWEEN_0_100(c1_time),socket_0.socket_num); logCpuCstates_dual_c(",",socket_0.socket_num); logCpuCstates_dual((float)THRESHOLD_BETWEEN_0_100(C3_time[i] * 100),socket_0.socket_num); logCpuCstates_dual_c(",",socket_0.socket_num); logCpuCstates_dual((float)THRESHOLD_BETWEEN_0_100(C6_time[i] * 100),socket_0.socket_num); if(prog_options.i7_version.sandy_bridge){ logCpuCstates_dual_c(",",socket_0.socket_num); logCpuCstates_dual((float)THRESHOLD_BETWEEN_0_100(C7_time[i] * 100),socket_0.socket_num); } logCpuCstates_dual_c("]\t",socket_0.socket_num); } logCloseFile_dual(socket_0.socket_num); mvprintw (8 + printw_offset, 0, " Real Current Frequency %0.2f MHz (Max of below)\n", TRUE_CPU_FREQ); refresh (); //shift the new values to the old counter values //so that the next time we use those to find the difference memcpy (old_val_CORE, new_val_CORE, sizeof (*old_val_CORE) * numCPUs); memcpy (old_val_REF, new_val_REF, sizeof (*old_val_REF) * numCPUs); memcpy (old_val_C3, new_val_C3, sizeof (*old_val_C3) * numCPUs); memcpy (old_val_C6, new_val_C6, sizeof (*old_val_C6) * numCPUs); if (prog_options.i7_version.sandy_bridge) { memcpy (old_val_C7, new_val_C7, sizeof (*old_val_C7) * numCPUs); } memcpy (tvstart, tvstop, sizeof (*tvstart) * numCPUs); memcpy (old_TSC, new_TSC, sizeof (*old_TSC) * numCPUs); } else { // If all the cores in the socket go offline, just erase the whole screen for (ii = 0 ; ii<14; ii++) mvprintw (3 + ii + printw_offset, 0, "\n"); } } void print_i7z () { struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); //print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); //print_socket_information(&socket_0); //print_socket_information(&socket_1); int printw_offset = (0) * 14; //Make an array size max 8 (to accomdate Nehalem-EXEX -lol) to store the core-num that are candidates for a given socket //removing it from here as it is already allocated in the function //int *core_list, core_list_size_phy, core_list_size_log; //iterator int i; //turbo_mode enabled/disabled flag char TURBO_MODE; double cpu_freq_cpuinfo; cpu_freq_cpuinfo = cpufreq_info (); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); //Print a slew of information on the ncurses window mvprintw (0, 0, "Cpu speed from cpuinfo %0.2fMhz\n", cpu_freq_cpuinfo); mvprintw (1, 0, "True Frequency (without accounting Turbo) %0.0f MHz\n",cpu_freq_cpuinfo); //MSR number and hi:low bit of that MSR //This msr contains a lot of stuff, per socket wise //one can pass any core number and then get in multiplier etc int PLATFORM_INFO_MSR = 206; //CE 15:8 int PLATFORM_INFO_MSR_low = 8; int PLATFORM_INFO_MSR_high = 15; unsigned long long int old_val_CORE[2][numCPUs_max], new_val_CORE[2][numCPUs_max]; unsigned long long int old_val_REF[2][numCPUs_max], new_val_REF[2][numCPUs_max]; unsigned long long int old_val_C3[2][numCPUs_max], new_val_C3[2][numCPUs_max]; unsigned long long int old_val_C6[2][numCPUs_max], new_val_C6[2][numCPUs_max]; unsigned long long int old_val_C7[2][numCPUs_max], new_val_C7[2][numCPUs_max]; unsigned long long int old_TSC[2][numCPUs_max], new_TSC[2][numCPUs_max]; long double C0_time[2][numCPUs_max], C1_time[2][numCPUs_max], C3_time[2][numCPUs_max], C6_time[2][numCPUs_max], C7_time[2][numCPUs_max]; double _FREQ[2][numCPUs_max], _MULT[2][numCPUs_max]; struct timeval tvstart[2][numCPUs_max], tvstop[2][numCPUs_max]; struct timespec one_second_sleep; one_second_sleep.tv_sec = 0; one_second_sleep.tv_nsec = 499999999; // 500msec //Get turbo mode status by reading msr within turbo_status TURBO_MODE = turbo_status (); //Flags and other things about HT. int HT_ON; char HT_ON_str[30]; int kk_1 = 11, kk_2 = 11; //below variables is used to monitor if any cores went offline etc. int online_cpus[MAX_PROCESSORS]; //Max 2 x Nehalem-EX with total 32 threads double estimated_mhz=0; int socket_num; //below variables stores how many cpus were observed till date for the socket int max_observed_cpu_socket1 = 0, max_observed_cpu_socket2 = 0; int k=0; for (;;) { construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); //HT enabled if num logical > num physical cores if (chi.HT==1) { strncpy (HT_ON_str, "Hyper Threading ON\0", 30); HT_ON = 1; } else { strncpy (HT_ON_str, "Hyper Threading OFF\0", 30); HT_ON = 0; } refresh (); SET_ONLINE_ARRAY_PLUS1(online_cpus) //In the function calls below socket_num is set to the socket to print for //printw_offset is the offset gap between the printing of the two sockets //kk_1 and kk_2 are the variables that have to be set, i have to use them internally //so in future if there are more sockets to be printed, add more kk_* socket_num=0; printw_offset=0; print_i7z_socket(socket_0, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_1, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num],old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num], new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num], C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_observed_cpu_socket1); /* // TEST CODE FOR CHECKING DUAL SOCK CODE ON SINGLE SOCKET MACHINE if(k<30){ socket_num=0; printw_offset=14; print_i7z_socket(socket_0, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_2, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_observed_cpu_socket2); }else{*/ socket_num=1; printw_offset=14; print_i7z_socket(socket_1, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_2, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num], old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num], new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num], C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_observed_cpu_socket2); //} k++; } } i7z-0.27.2/helper_functions.c0000644000175000017500000005714712023553432014433 0ustar abhiabhi/* This file is modified from source available at http://www.kernel.org/pub/linux/utils/cpu/msr-tools/ for Model specific cpu registers Modified to take i7 into account by Abhishek Jaiantilal abhishek.jaiantilal@colorado.edu // Information about i7's MSR in // http://download.intel.com/design/processor/applnots/320354.pdf // Appendix B of http://www.intel.com/Assets/PDF/manual/253669.pdf //about rdmsr #ident "$Id: rdmsr.c,v 1.4 2004/07/20 15:54:59 hpa Exp $" ----------------------------------------------------------------------- * * * Copyright 2000 Transmeta Corporation - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA; * either version 2 of the License, or (at your option) any later * version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "i7z.h" //#define ULLONG_MAX 18446744073709551615 extern struct program_options prog_options; bool E7_mp_present=false; /////////////////////////////////////////READ TEMPERATURE//////////////////////////////////////////// #define IA32_THERM_STATUS 0x19C #define IA32_TEMPERATURE_TARGET 0x1a2 #define IA32_PACKAGE_THERM_STATUS 0x1b1 int Get_Bits_Value(unsigned long val,int highbit, int lowbit){ unsigned long data = val; int bits = highbit - lowbit + 1; if(bits<64){ data >>= lowbit; data &= (1ULL<stepping); printf ("i7z DEBUG: Model %x\n", proc_info->model); printf ("i7z DEBUG: Family %x\n", proc_info->family); printf ("i7z DEBUG: Processor Type %x\n", proc_info->processor_type); printf ("i7z DEBUG: Extended Model %x\n", proc_info->extended_model); // printf(" Extended Family %x\n", (short int*)(&proc_info->extended_family)); // printf(" Extended Family %d\n", proc_info->extended_family); } static inline void cpuid (unsigned int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { unsigned int _eax = info, _ebx, _ecx, _edx; asm volatile ("mov %%ebx, %%edi;" // save ebx (for PIC) "cpuid;" "mov %%ebx, %%esi;" // pass to caller "mov %%edi, %%ebx;" // restore ebx :"+a" (_eax), "=S" (_ebx), "=c" (_ecx), "=d" (_edx) : /* inputs: eax is handled above */ :"edi" /* clobbers: we hit edi directly */); if (eax) *eax = _eax; if (ebx) *ebx = _ebx; if (ecx) *ecx = _ecx; if (edx) *edx = _edx; } static inline void get_vendor (char *vendor_string) { //get vendor name unsigned int a, b, c, d; cpuid (0, &a, &b, &c, &d); memcpy (vendor_string, &b, 4); memcpy (&vendor_string[4], &d, 4); memcpy (&vendor_string[8], &c, 4); vendor_string[12] = '\0'; // printf("Vendor %s\n",vendor_string); } int turbo_status () { //turbo state flag unsigned int eax; cpuid (6, &eax, NULL, NULL, NULL); //printf("eax %d\n",(eax&0x2)>>1); return ((eax & 0x2) >> 1); } static inline void get_familyinformation (struct family_info *proc_info) { //get info about CPU unsigned int b; cpuid (1, &b, NULL, NULL, NULL); // printf ("eax %x\n", b); proc_info->stepping = b & 0x0000000F; //bits 3:0 proc_info->model = (b & 0x000000F0) >> 4; //bits 7:4 proc_info->family = (b & 0x00000F00) >> 8; //bits 11:8 proc_info->processor_type = (b & 0x00007000) >> 12; //bits 13:12 proc_info->extended_model = (b & 0x000F0000) >> 16; //bits 19:16 proc_info->extended_family = (b & 0x0FF00000) >> 20; //bits 27:20 } double estimate_MHz () { //copied blantantly from http://www.cs.helsinki.fi/linux/linux-kernel/2001-37/0256.html /* * $Id: MHz.c,v 1.4 2001/05/21 18:58:01 davej Exp $ * This file is part of x86info. * (C) 2001 Dave Jones. * * Licensed under the terms of the GNU GPL License version 2. * * Estimate CPU MHz routine by Andrea Arcangeli * Small changes by David Sterba * */ struct timezone tz; struct timeval tvstart, tvstop; unsigned long long int cycles[2]; /* gotta be 64 bit */ unsigned long long int microseconds; /* total time taken */ memset (&tz, 0, sizeof (tz)); /* get this function in cached memory */ gettimeofday (&tvstart, &tz); cycles[0] = rdtsc (); gettimeofday (&tvstart, &tz); /* we don't trust that this is any specific length of time */ //1 sec will cause rdtsc to overlap multiple times perhaps. 100msecs is a good spot usleep (10000); cycles[1] = rdtsc (); gettimeofday (&tvstop, &tz); microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) + (tvstop.tv_usec - tvstart.tv_usec); unsigned long long int elapsed = 0; if (cycles[1] < cycles[0]) { //printf("c0 = %llu c1 = %llu",cycles[0],cycles[1]); elapsed = UINT32_MAX - cycles[0]; elapsed = elapsed + cycles[1]; //printf("c0 = %llu c1 = %llu max = %llu elapsed=%llu\n",cycles[0], cycles[1], UINT32_MAX,elapsed); } else { elapsed = cycles[1] - cycles[0]; //printf("\nc0 = %llu c1 = %llu elapsed=%llu\n",cycles[0], cycles[1],elapsed); } double mhz = elapsed / microseconds; //printf("%llg MHz processor (estimate). diff cycles=%llu microseconds=%llu \n", mhz, elapsed, microseconds); //printf("%g elapsed %llu microseconds %llu\n",mhz, elapsed, microseconds); return (mhz); } /* Number of decimal digits for a certain number of bits */ /* (int) ceil(log(2^n)/log(10)) */ int decdigits[] = { 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20 }; #define mo_hex 0x01 #define mo_dec 0x02 #define mo_oct 0x03 #define mo_raw 0x04 #define mo_uns 0x05 #define mo_chx 0x06 #define mo_mask 0x0f #define mo_fill 0x40 #define mo_c 0x80 const char *program; uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, unsigned int lowbit, int* error_indx) { uint64_t data; int fd; // char *pat; // int width; char msr_file_name[64]; int bits; *error_indx =0; sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); fd = open (msr_file_name, O_RDONLY); if (fd < 0) { if (errno == ENXIO) { //fprintf (stderr, "rdmsr: No CPU %d\n", cpu); *error_indx = 1; return 1; } else if (errno == EIO) { //fprintf (stderr, "rdmsr: CPU %d doesn't support MSRs\n", cpu); *error_indx = 1; return 1; } else { //perror ("rdmsr:open"); *error_indx = 1; return 1; //exit (127); } } if (pread (fd, &data, sizeof data, reg) != sizeof data) { perror ("rdmsr:pread"); exit (127); } close (fd); bits = highbit - lowbit + 1; if (bits < 64) { /* Show only part of register */ data >>= lowbit; data &= (1ULL << bits) - 1; } /* Make sure we get sign correct */ if (data & (1ULL << (bits - 1))) { data &= ~(1ULL << (bits - 1)); data = -data; } *error_indx = 0; return (data); } uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data) { int fd; char msr_file_name[64]; sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); fd = open (msr_file_name, O_WRONLY); if (fd < 0) { if (errno == ENXIO) { fprintf (stderr, "wrmsr: No CPU %d\n", cpu); exit (2); } else if (errno == EIO) { fprintf (stderr, "wrmsr: CPU %d doesn't support MSRs\n", cpu); exit (3); } else { perror ("wrmsr:open"); exit (127); } } if (pwrite (fd, &data, sizeof data, reg) != sizeof data) { perror ("wrmsr:pwrite"); exit (127); } close(fd); return(1); } #ifdef USE_INTEL_CPUID void get_CPUs_info (unsigned int *num_Logical_OS, unsigned int *num_Logical_process, unsigned int *num_Processor_Core, unsigned int *num_Physical_Socket); #endif //Below code /* ----------------------------------------------------------------------- * * * Copyright 2010 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ void Print_Version_Information() { printf ("i7z DEBUG: i7z version: %s\n",i7z_VERSION_INFO); } //sets whether its nehalem or sandy bridge void Print_Information_Processor(bool* nehalem, bool* sandy_bridge) { struct family_info proc_info; char vendor_string[13]; memset(vendor_string,0,13); get_vendor (vendor_string); vendor_string[12] = '\0'; //look at the blurb below for why strcmp is done byte by byte /* bool equal_string = true; char const* genuine_intel_str = "GenuineIntel"; int i; for(i=0; i<12;i++) { if (vendor_string[i] != genuine_intel_str[i]) equal_string = false; } */ // somehow using strcmp or strncmp is crashing the app when using -O2, -O3 with gcc-4.7 // (strncmp (vendor_string, "GenuineIntel",12) == 0) // (strcmp (vendor_string, "GenuineIntel",12) == 0) if (strcmp (vendor_string, "GenuineIntel") == 0) { //if (equal_string) { printf ("i7z DEBUG: Found Intel Processor\n"); } else { printf ("this was designed to be a intel proc utility. You can perhaps mod it for your machine?\n"); exit (1); } get_familyinformation (&proc_info); print_family_info (&proc_info); //printf("%x %x",proc_info.extended_model,proc_info.family); //check if its nehalem or exit //Info from page 641 of Intel Manual 3B //Extended model and Model can help determine the right cpu //furthermore from pdf 241618.pdf from intel //page 24, got the following info //extended model is either 0x1 or 0x2 //check on model number as follows //extended model, model no - processor type //0x1, 0xA - i7, 45nm //0x1, 0xE - i7, i5, Xeon, 45nm //0x2, 0xE - Xeon MP, 45nm //e.g. x75xx processors //0x2, 0xF - Xeon MP, 32nm //e.g. e7-48xx processors //0x2, 0xC - i7, Xeon, 32nm //0x2, 0x5 - i3, i5, i7 mobile processors, 32nm //0x2, 0xA - i7, 32nm //http://ark.intel.com/SSPECQDF.aspx //http://software.intel.com/en-us/articles/intel-processor-identification-with-cpuid-model-and-family-numbers/ printf("i7z DEBUG: msr = Model Specific Register\n"); if (proc_info.family >= 0x6) { if (proc_info.extended_model == 0x1) { switch (proc_info.model) { case 0xA: printf ("i7z DEBUG: Detected a nehalem (i7) - 45nm\n"); break; case 0xE: case 0xF: printf ("i7z DEBUG: Detected a nehalem (i7/i5/Xeon) - 45nm\n"); break; default: printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); //exit (1); } *nehalem = true; *sandy_bridge = false; } else if (proc_info.extended_model == 0x2) { switch (proc_info.model) { case 0xE: printf ("i7z DEBUG: Detected a Xeon MP - 45nm (7500, 6500 series)\n"); *nehalem = true; *sandy_bridge = false; break; case 0xF: printf ("i7z DEBUG: Detected a Xeon MP - 32nm (E7 series)\n"); *nehalem = true; *sandy_bridge = false; E7_mp_present = true; break; case 0xC: *nehalem = true; *sandy_bridge = false; printf ("i7z DEBUG: Detected an i7/Xeon - 32 nm (westmere)\n"); break; case 0x5: *nehalem = true; *sandy_bridge = false; printf ("i7z DEBUG: Detected an i3/i5/i7 - 32nm (westmere - 1st generation core)\n"); break; case 0xD: *nehalem = false; *sandy_bridge = true; printf ("i7z DEBUG: Detected an i7 - 32nm (haven't seen this version around, do write to me with the model number)\n"); break; case 0xA: *nehalem = false; *sandy_bridge = true; printf ("i7z DEBUG: Detected an i3/i5/i7 - 32nm (sandy bridge - 2nd generation core)\n"); break; default: printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); printf("i7z DEBUG: detected a newer model of ivy bridge processor\n"); printf("i7z DEBUG: my coder doesn't know about it, can you send the following info to him?\n"); printf("i7z DEBUG: model %x, extended model %x, proc_family %x\n", proc_info.model, proc_info.extended_model, proc_info.family); //exit (1); } } else if (proc_info.extended_model == 0x3) { switch (proc_info.model) { case 0xA: printf ("i7z DEBUG: Detected an ivy bridege processor\n"); *nehalem = false; *sandy_bridge = true; break; default: printf("i7z DEBUG: detected a newer model of ivy bridge processor\n"); printf("i7z DEBUG: my coder doesn't know about it, can you send the following info to him?\n"); printf("i7z DEBUG: model %x, extended model %x, proc_family %x\n", proc_info.model, proc_info.extended_model, proc_info.family); sleep(5); } } else { printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem, Sandy bridge or Ivy Bridge\n"); //exit (1); } } else { printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); exit (1); } } void Test_Or_Make_MSR_DEVICE_FILES() { //test if the msr file exists if (access ("/dev/cpu/0/msr", F_OK) == 0) { printf ("i7z DEBUG: msr device files exist /dev/cpu/*/msr\n"); if (access ("/dev/cpu/0/msr", W_OK) == 0) { //a system mght have been set with msr allowable to be written //by a normal user so... //Do nothing. printf ("i7z DEBUG: You have write permissions to msr device files\n"); } else { printf ("i7z DEBUG: You DONOT have write permissions to msr device files\n"); printf ("i7z DEBUG: A solution is to run this program as root\n"); exit (1); } } else { printf ("i7z DEBUG: msr device files DONOT exist, trying out a makedev script\n"); if (geteuid () == 0) { //Try the Makedev script //sourced from MAKEDEV-cpuid-msr script in msr-tools system ("msr_major=202; \ cpuid_major=203; \ n=0; \ while [ $n -lt 16 ]; do \ mkdir -m 0755 -p /dev/cpu/$n; \ mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n; \ mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n; \ n=`expr $n + 1`; \ done; \ "); printf ("i7z DEBUG: modprobbing for msr\n"); system ("modprobe msr"); } else { printf ("i7z DEBUG: You DONOT have root privileges, mknod to create device entries won't work out\n"); printf ("i7z DEBUG: A solution is to run this program as root\n"); exit (1); } } } double cpufreq_info() { //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ system ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo FILE *tmp_file; tmp_file = fopen ("/tmp/cpufreq.txt", "r"); char tmp_str[30]; fgets (tmp_str, 30, tmp_file); fclose (tmp_file); return atof(tmp_str); } int check_and_return_processor(char*strinfo) { char *t1; if (strstr(strinfo,"processor") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } int check_and_return_physical_id(char*strinfo) { char *t1; if (strstr(strinfo,"physical id") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } int check_and_return_core_id(char*strinfo) { char *t1; if (strstr(strinfo,"core id") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } void construct_sibling_list(struct cpu_heirarchy_info* chi) { int i,j,core_id,socket_id; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); chi->sibling_num[i]=-1; } chi->HT=false; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); core_id = chi->coreid_num[i]; socket_id = chi->package_num[i]; for (j=i+1;j< chi->max_online_cpu ;j++) { assert(j < MAX_HI_PROCESSORS); if (chi->coreid_num[j] == core_id && chi->package_num[j] == socket_id) { chi->sibling_num[j] = i; chi->sibling_num[i] = j; chi->display_cores[i] = 1; chi->display_cores[j] = -1; chi->HT=true; continue; } } } //for cores that donot have a sibling put in 1 for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); if (chi->sibling_num[i] ==-1) chi->display_cores[i] = 1; } } void construct_socket_information(struct cpu_heirarchy_info* chi, struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1, int socket_0_num, int socket_1_num) { int i; socket_0->max_cpu=0; socket_0->num_physical_cores=0; socket_0->num_logical_cores=0; socket_1->max_cpu=0; socket_1->num_physical_cores=0; socket_1->num_logical_cores=0; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); if (chi->display_cores[i]!=-1) { if (chi->package_num[i]==socket_0_num) { assert(socket_0->max_cpu < MAX_SK_PROCESSORS); socket_0->processor_num[socket_0->max_cpu]=chi->processor_num[i]; socket_0->max_cpu++; socket_0->num_physical_cores++; socket_0->num_logical_cores++; } if (chi->package_num[i]==socket_1_num) { assert(socket_1->max_cpu < MAX_SK_PROCESSORS); socket_1->processor_num[socket_1->max_cpu]=chi->processor_num[i]; socket_1->max_cpu++; socket_1->num_physical_cores++; socket_1->num_logical_cores++; } } else { if (chi->package_num[i]==socket_0_num) { socket_0->num_logical_cores++; } if (chi->package_num[i]==socket_1_num) { socket_1->num_logical_cores++; } } } } void print_socket_information(struct cpu_socket_info* socket) { int i; char socket_list[200]=""; for (i=0;i< socket->max_cpu ;i++) { assert(i < MAX_SK_PROCESSORS); if (socket->processor_num[i]!=-1) { sprintf(socket_list,"%s%d,",socket_list,socket->processor_num[i]); } } printf("Socket-%d [num of cpus %d physical %d logical %d] %s\n",socket->socket_num,socket->max_cpu,socket->num_physical_cores,socket->num_logical_cores,socket_list); } void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi) { FILE *fp = fopen("/proc/cpuinfo","r"); char strinfo[200]; int processor_num, physicalid_num, coreid_num; int it_processor_num=-1, it_physicalid_num=-1, it_coreid_num=-1; int tmp_processor_num, tmp_physicalid_num, tmp_coreid_num; int old_processor_num=-1; memset(chi, 0, sizeof(*chi)); if (fp!=NULL) { while ( fgets(strinfo,200,fp) != NULL) { // printf(strinfo); tmp_processor_num = check_and_return_processor(strinfo); tmp_physicalid_num = check_and_return_physical_id(strinfo); tmp_coreid_num = check_and_return_core_id(strinfo); if (tmp_processor_num != -1) { it_processor_num++; processor_num = tmp_processor_num; assert(it_processor_num < MAX_HI_PROCESSORS); chi->processor_num[it_processor_num] = processor_num; } if (tmp_physicalid_num != -1) { it_physicalid_num++; physicalid_num = tmp_physicalid_num; assert(it_physicalid_num < MAX_HI_PROCESSORS); chi->package_num[it_physicalid_num] = physicalid_num; } if (tmp_coreid_num != -1) { it_coreid_num++; coreid_num = tmp_coreid_num; assert(it_coreid_num < MAX_HI_PROCESSORS); chi->coreid_num[it_coreid_num] = coreid_num; } if (processor_num != old_processor_num) { old_processor_num = processor_num; } } } chi->max_online_cpu = it_processor_num+1; fclose(fp); } void print_CPU_Heirarchy(struct cpu_heirarchy_info chi) { int i; printf("\n------------------------------\n--[core id]--- Other information\n-------------------------------------\n"); for (i=0;i < chi.max_online_cpu;i++) { assert(i < MAX_HI_PROCESSORS); printf("--[%d] Processor number %d\n",i,chi.processor_num[i]); printf("--[%d] Socket number/Hyperthreaded Sibling number %d,%d\n",i,chi.package_num[i],chi.sibling_num[i]); printf("--[%d] Core id number %d\n",i,chi.coreid_num[i]); printf("--[%d] Display core in i7z Tool: %s\n\n",i,(chi.display_cores[i]==1)?"Yes":"No"); } } int in_core_list(int ii,int* core_list) { int i; int in=0; for (i=0;i<8;i++) { if (ii == core_list[i]) { in=1; break; } } return(in); } bool file_exists(char* filename) { if (access(filename, F_OK) == 0) { return true; } else { return false; } } i7z-0.27.2/GUI/0000755000175000017500000000000012023752313011325 5ustar abhiabhii7z-0.27.2/GUI/i7z_GUI.cpp0000644000175000017500000005765012023553432013264 0ustar abhiabhi/* ----------------------------------------------------------------------- * * * Copyright 2009 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef UINT32_MAX # define UINT32_MAX (4294967295U) #endif #include "../helper_functions.c" #define MAX_PROCESSORS_GUI 12 bool global_in_i7z_main_thread = false; int socket_list[MAX_PROCESSORS_GUI]; int core_list[MAX_PROCESSORS_GUI]; struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0, socket_1; unsigned int numCPUs; struct program_options prog_options; void Construct_Socket_Information_in_GUI(unsigned int *numCPUs) { int socket_0_num=0, socket_1_num=1; socket_0.max_cpu=0; socket_0.socket_num=0; int i; for(i=0;i < 8; i++) socket_0.processor_num[i]=-1; socket_1.max_cpu=0; socket_1.socket_num=1; for(i=0;i < 8; i++) socket_1.processor_num[i]=-1; construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); // print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); // print_socket_information(&socket_0); // print_socket_information(&socket_1); *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; //// FOR DEBUGGING DUAL SOCKET CODE ON SINGLE SOCKET, UNCOMMENT BELOW 2 lines // memcpy(&socket_1, &socket_0, sizeof(struct cpu_socket_info)); // socket_1.socket_num=0; // print_socket_information(&socket_0); // print_socket_information(&socket_1); *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; // printf("My Widget: Num Processors %d\n",*numCPUs); int k, ii; k=0; for (ii = 0; ii < socket_0.num_physical_cores ; ii++) { if ( socket_0.processor_num[ii] != -1) { core_list[k] = socket_0.processor_num[ii]; socket_list[k] = 0; k++; } } for (ii = 0; ii < socket_1.num_physical_cores ; ii++) { if ( socket_1.processor_num[ii] != -1) { core_list[k] = socket_1.processor_num[ii]; socket_list[k] = 1; k++; } } } class MyThread:public QThread { public: MyThread (); void run (); double *FREQ, *MULT; long double *C0_TIME, *C1_TIME, *C3_TIME, *C6_TIME; }; MyThread::MyThread () { Construct_Socket_Information_in_GUI(&numCPUs); //allocate space for the variables FREQ = (double *) malloc (sizeof (double) * numCPUs); MULT = (double *) malloc (sizeof (double) * numCPUs); C0_TIME = (long double *) malloc (sizeof (long double) * numCPUs); C1_TIME = (long double *) malloc (sizeof (long double) * numCPUs); C3_TIME = (long double *) malloc (sizeof (long double) * numCPUs); C6_TIME = (long double *) malloc (sizeof (long double) * numCPUs); int i; for (i = 0; i < (int)numCPUs; i++) { FREQ[i] = 0; MULT[i] = 0; C0_TIME[i] = 0; C1_TIME[i] = 0; C3_TIME[i] = 0; C6_TIME[i] = 0; } } void MyThread::run () { print_CPU_Heirarchy(chi); int i, ii; //MSR number and hi:low bit of that MSR //This msr contains a lot of stuff, per socket wise //one can pass any core number and then get in multiplier etc int PLATFORM_INFO_MSR = 206; //CE 15:8 int PLATFORM_INFO_MSR_low = 8; int PLATFORM_INFO_MSR_high = 15; ////To find out if Turbo is enabled use the below msr and bit 38 ////bit for TURBO is 38 ////msr reading is now moved into tubo_status //int IA32_MISC_ENABLE = 416; //int TURBO_FLAG_low = 38; //int TURBO_FLAG_high = 38; //int MSR_TURBO_RATIO_LIMIT = 429; int CPU_NUM; int CPU_Multiplier; float BLCK; char TURBO_MODE; printf("i7z DEBUG: GUI VERSION DOESN'T SUPPORT CORE OFFLINING\n"); sleep (1); // 3B defines till Max 4 Core and the rest bit values from 32:63 were reserved. // int MAX_TURBO_1C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 7, 0); // int MAX_TURBO_2C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 15, 8); // int MAX_TURBO_3C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 23, 16); // int MAX_TURBO_4C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 31, 24); //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ system ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); system ("grep \"core id\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numPhysical.txt"); system ("grep \"processor\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numLogical.txt"); //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo FILE *tmp_file; tmp_file = fopen ("/tmp/cpufreq.txt", "r"); char tmp_str[30]; fgets (tmp_str, 30, tmp_file); double cpu_freq_cpuinfo = atof (tmp_str); fclose (tmp_file); unsigned int numPhysicalCores, numLogicalCores; numPhysicalCores = socket_0.num_physical_cores + socket_1.num_physical_cores; numLogicalCores = socket_0.num_logical_cores + socket_1.num_logical_cores; // printf("My thread: Num Processors %d\n",numCPUs); int error_indx; //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); //We just need one CPU (we use Core-0) to figure out the multiplier and the bus clock freq. CPU_NUM = 0; CPU_Multiplier = get_msr_value (CPU_NUM, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &error_indx); BLCK = cpu_freq_cpuinfo / CPU_Multiplier; TURBO_MODE = turbo_status (); //get_msr_value(CPU_NUM,IA32_MISC_ENABLE, TURBO_FLAG_high,TURBO_FLAG_low); //to find how many cpus are enabled, we could have used sysconf but that will just give the logical numbers //if HT is enabled then the threads of the same core have the same C-state residency number so... //Its imperative to figure out the number of physical and number of logical cores. //sysconf(_SC_NPROCESSORS_ONLN); bool HT_ON; char HT_ON_str[30]; if (numLogicalCores > numPhysicalCores) { strcpy (HT_ON_str, "Hyper Threading ON"); HT_ON = true; } else { strcpy (HT_ON_str, "Hyper Threading OFF"); HT_ON = false; } float TRUE_CPU_FREQ; if (TURBO_MODE == 1) { TRUE_CPU_FREQ = BLCK * ((double)CPU_Multiplier + 1); } else { TRUE_CPU_FREQ = BLCK * ((double)CPU_Multiplier); } int IA32_PERF_GLOBAL_CTRL = 911; //3BF int IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0,&error_indx); int IA32_FIXED_CTR_CTL = 909; //38D int IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0,&error_indx); //printf("IA32_PERF_GLOBAL_CTRL %d\n",IA32_PERF_GLOBAL_CTRL_Value); //printf("IA32_FIXED_CTR_CTL %d\n",IA32_FIXED_CTR_CTL_Value); unsigned long long int CPU_CLK_UNHALTED_CORE, CPU_CLK_UNHALTED_REF, CPU_CLK_C3, CPU_CLK_C6, CPU_CLK_C1; CPU_CLK_UNHALTED_CORE = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); CPU_CLK_UNHALTED_REF = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); unsigned long long int old_val_CORE[numCPUs], new_val_CORE[numCPUs]; unsigned long long int old_val_REF[numCPUs], new_val_REF[numCPUs]; unsigned long long int old_val_C3[numCPUs], new_val_C3[numCPUs]; unsigned long long int old_val_C6[numCPUs], new_val_C6[numCPUs]; // unsigned long int old_val_C1[numCPUs], new_val_C1[numCPUs]; unsigned long long int old_TSC[numCPUs], new_TSC[numCPUs]; struct timeval tvstart[numCPUs], tvstop[numCPUs]; struct timespec one_second_sleep; one_second_sleep.tv_sec = 0; one_second_sleep.tv_nsec = 999999999; // 1000msec unsigned long int IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0,&error_indx); unsigned long int IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0,&error_indx); // mvprintw(12,0,"Wait...\n"); refresh(); nanosleep (&one_second_sleep, NULL); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx) - IA32_MPERF; IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx) - IA32_APERF; //printf("Diff. i n APERF = %u, MPERF = %d\n", IA32_MPERF, IA32_APERF); long double C0_time[numCPUs], C1_time[numCPUs], C3_time[numCPUs], C6_time[numCPUs]; double _FREQ[numCPUs], _MULT[numCPUs]; // mvprintw(12,0,"Current Freqs\n"); int kk=11; double estimated_mhz; for (;;) { Construct_Socket_Information_in_GUI(&numCPUs); if (kk>10) { kk=0; for (ii = 0; ii < (int)numCPUs; ii++) { CPU_NUM = core_list[ii]; IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); set_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 0x700000003LLU); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); set_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 819); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); old_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); old_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); old_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0,&error_indx); old_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0,&error_indx); old_TSC[ii] = rdtsc (); } } kk++; nanosleep (&one_second_sleep, NULL); estimated_mhz = estimate_MHz(); for (i = 0; i < (int)numCPUs; i++) { CPU_NUM = core_list[i]; new_val_CORE[i] = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); new_val_REF[i] = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); new_val_C3[i] = get_msr_value (CPU_NUM, 1020, 63, 0,&error_indx); new_val_C6[i] = get_msr_value (CPU_NUM, 1021, 63, 0,&error_indx); new_TSC[i] = rdtsc (); if (old_val_CORE[i] > new_val_CORE[i]) { CPU_CLK_UNHALTED_CORE = (3.40282366921e38 - old_val_CORE[i]) + new_val_CORE[i]; } else { CPU_CLK_UNHALTED_CORE = new_val_CORE[i] - old_val_CORE[i]; } //number of TSC cycles while its in halted state if ((new_TSC[i] - old_TSC[i]) < CPU_CLK_UNHALTED_CORE) CPU_CLK_C1 = 0; else CPU_CLK_C1 = ((new_TSC[i] - old_TSC[i]) - CPU_CLK_UNHALTED_CORE); if (old_val_REF[i] > new_val_REF[i]) { CPU_CLK_UNHALTED_REF = (3.40282366921e38 - old_val_REF[i]) + new_val_REF[i]; } else { CPU_CLK_UNHALTED_REF = new_val_REF[i] - old_val_REF[i]; } if (old_val_C3[i] > new_val_C3[i]) { CPU_CLK_C3 = (3.40282366921e38 - old_val_C3[i]) + new_val_C3[i]; } else { CPU_CLK_C3 = new_val_C3[i] - old_val_C3[i]; } if (old_val_C6[i] > new_val_C6[i]) { CPU_CLK_C6 = (3.40282366921e38 - old_val_C6[i]) + new_val_C6[i]; } else { CPU_CLK_C6 = new_val_C6[i] - old_val_C6[i]; } _FREQ[i] = estimated_mhz * ((long double) CPU_CLK_UNHALTED_CORE / (long double) CPU_CLK_UNHALTED_REF); _MULT[i] = _FREQ[i] / BLCK; C0_time[i] = ((long double) CPU_CLK_UNHALTED_REF / (long double) (new_TSC[i] - old_TSC[i])); long double c1_time = ((long double) CPU_CLK_C1 / (long double) (new_TSC[i] - old_TSC[i])); C3_time[i] = ((long double) CPU_CLK_C3 / (long double) (new_TSC[i] - old_TSC[i])); C6_time[i] = ((long double) CPU_CLK_C6 / (long double) (new_TSC[i] - old_TSC[i])); //C1_time[i] -= C3_time[i] + C6_time[i]; C1_time[i] = c1_time - (C3_time[i] + C6_time[i]) ; if (!isnan(c1_time) && !isinf(c1_time)) { if (C1_time[i] <= 0) { C1_time[i]=0; } } if (C0_time[i] < 1e-2) { if (C0_time[i] > 1e-4) C0_time[i] = 0.01; else C0_time[i] = 0; } if (C1_time[i] < 1e-2) { if (C1_time[i] > 1e-4) C1_time[i] = 0.01; else C1_time[i] = 0; } if (C3_time[i] < 1e-2) { if (C3_time[i] > 1e-4) C3_time[i] = 0.01; else C3_time[i] = 0; } if (C6_time[i] < 1e-2) { if (C6_time[i] > 1e-4) C6_time[i] = 0.01; else C6_time[i] = 0; } } // printf("Hello"); // for(i=0;i TRUE_CPU_FREQ) TRUE_CPU_FREQ = _FREQ[i]; memcpy (old_val_CORE, new_val_CORE, sizeof (unsigned long int) * numCPUs); memcpy (old_val_REF, new_val_REF, sizeof (unsigned long int) * numCPUs); memcpy (old_val_C3, new_val_C3, sizeof (unsigned long int) * numCPUs); memcpy (old_val_C6, new_val_C6, sizeof (unsigned long int) * numCPUs); memcpy (tvstart, tvstop, sizeof (struct timeval) * numCPUs); memcpy (old_TSC, new_TSC, sizeof (unsigned long long int) * numCPUs); memcpy (FREQ, _FREQ, sizeof (double) * numCPUs); memcpy (MULT, _MULT, sizeof (double) * numCPUs); memcpy (C0_TIME, C0_time, sizeof (long double) * numCPUs); memcpy (C1_TIME, C1_time, sizeof (long double) * numCPUs); memcpy (C3_TIME, C3_time, sizeof (long double) * numCPUs); memcpy (C6_TIME, C6_time, sizeof (long double) * numCPUs); global_in_i7z_main_thread = true; } } class MyWidget:public QWidget { Q_OBJECT public: QProgressBar * C0_l[MAX_PROCESSORS_GUI], *C1_l[MAX_PROCESSORS_GUI], *C3_l[MAX_PROCESSORS_GUI], *C6_l[MAX_PROCESSORS_GUI]; QLabel *C0, *C1, *C3, *C6; QLabel *Freq_[MAX_PROCESSORS_GUI]; QLabel *StatusMessage0, *StatusMessage1, *Curr_Freq0, *Curr_Freq1; QLabel *ProcNames[MAX_PROCESSORS_GUI]; MyWidget (QWidget * parent = 0); MyThread *mythread; int curr_numCPUs; private slots: void UpdateWidget (); }; MyWidget::MyWidget (QWidget * parent):QWidget (parent) { Print_Version_Information(); // //Print_Information_Processor (); bool cpuNehalem, cpuSandybridge; Print_Information_Processor (&cpuNehalem, &cpuSandybridge); Test_Or_Make_MSR_DEVICE_FILES (); Construct_Socket_Information_in_GUI(&numCPUs); char processor_str[100]; // printf("MyWidget: Num Processors %d\n",numCPUs); int i; for (i = 0; i < (int)numCPUs; i++) { C0_l[i] = new QProgressBar; C0_l[i]->setMaximum (99); C0_l[i]->setMinimum (0); C1_l[i] = new QProgressBar; C1_l[i]->setMaximum (99); C1_l[i]->setMinimum (0); C3_l[i] = new QProgressBar; C3_l[i]->setMaximum (99); C3_l[i]->setMinimum (0); C6_l[i] = new QProgressBar; C6_l[i]->setMaximum (99); C6_l[i]->setMinimum (0); Freq_[i] = new QLabel (tr ("")); } QGridLayout * layout1 = new QGridLayout; curr_numCPUs = numCPUs; for (i = 0; i < (int)numCPUs; i++) { layout1->addWidget (C0_l[i], i + 1, 1); layout1->addWidget (C1_l[i], i + 1, 2); layout1->addWidget (C3_l[i], i + 1, 3); layout1->addWidget (C6_l[i], i + 1, 4); } C0 = new QLabel (tr ("C0")); C0->setAlignment (Qt::AlignCenter); C1 = new QLabel (tr ("C1")); C1->setAlignment (Qt::AlignCenter); C3 = new QLabel (tr ("C3")); C3->setAlignment (Qt::AlignCenter); C6 = new QLabel (tr ("C6")); C6->setAlignment (Qt::AlignCenter); snprintf(processor_str, 100, "Core-1 [id:%d,socket:%d]",core_list[0],socket_list[0]); ProcNames[0] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-2 [id:%d,socket:%d]",core_list[1],socket_list[1]); ProcNames[1] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-3 [id:%d,socket:%d]",core_list[2],socket_list[2]); ProcNames[2] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-4 [id:%d,socket:%d]",core_list[3],socket_list[3]); ProcNames[3] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-5 [id:%d,socket:%d]",core_list[4],socket_list[4]); ProcNames[4] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-6 [id:%d,socket:%d]",core_list[5],socket_list[5]); ProcNames[5] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-7 [id:%d,socket:%d]",core_list[6],socket_list[6]); ProcNames[6] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-8 [id:%d,socket:%d]",core_list[7],socket_list[7]); ProcNames[7] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-9 [id:%d,socket:%d]",core_list[8],socket_list[8]); ProcNames[8] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-10 [id:%d,socket:%d]",core_list[9],socket_list[9]); ProcNames[9] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-11 [id:%d,socket:%d]",core_list[10],socket_list[10]); ProcNames[10] = new QLabel (tr (processor_str)); snprintf(processor_str, 100, "Core-12 [id:%d,socket:%d]",core_list[11],socket_list[11]); ProcNames[11] = new QLabel (tr (processor_str)); StatusMessage0 = new QLabel (tr ("Wait")); Curr_Freq0 = new QLabel (tr ("Wait")); if ( (socket_0.num_physical_cores > 0) && (socket_1.num_physical_cores > 0)) { StatusMessage1 = new QLabel (tr ("Wait")); Curr_Freq1 = new QLabel (tr ("Wait")); } for (i = 0; i < (int)numCPUs; i++) { layout1->addWidget (ProcNames[i], i + 1, 0); } layout1->addWidget (C0, 0, 1); layout1->addWidget (C1, 0, 2); layout1->addWidget (C3, 0, 3); layout1->addWidget (C6, 0, 4); for (i = 0; i < (int)numCPUs; i++) layout1->addWidget (Freq_[i], i + 1, 5); layout1->addWidget (StatusMessage0, numCPUs + 1, 4); layout1->addWidget (Curr_Freq0, numCPUs + 1, 5); if ( (socket_0.num_physical_cores > 0) && (socket_1.num_physical_cores > 0)) { layout1->addWidget (StatusMessage1, numCPUs + 2, 4); layout1->addWidget (Curr_Freq1, numCPUs + 2, 5); } QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout ()), this, SLOT (UpdateWidget ())); timer->start (1000); mythread = new MyThread (); mythread->start (); setLayout (layout1); } void MyWidget::UpdateWidget () { char processor_str[100]; snprintf(processor_str, 100, "Core-1 [id:%d,socket:%d]",core_list[0],socket_list[0]); ProcNames[0]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-2 [id:%d,socket:%d]",core_list[1],socket_list[1]); ProcNames[1]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-3 [id:%d,socket:%d]",core_list[2],socket_list[2]); ProcNames[2]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-4 [id:%d,socket:%d]",core_list[3],socket_list[3]); ProcNames[3]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-5 [id:%d,socket:%d]",core_list[4],socket_list[4]); ProcNames[4]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-6 [id:%d,socket:%d]",core_list[5],socket_list[5]); ProcNames[5]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-7 [id:%d,socket:%d]",core_list[6],socket_list[6]); ProcNames[6]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-8 [id:%d,socket:%d]",core_list[7],socket_list[7]); ProcNames[7]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-9 [id:%d,socket:%d]",core_list[8],socket_list[8]); ProcNames[8]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-10 [id:%d,socket:%d]",core_list[9],socket_list[9]); ProcNames[9]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-11 [id:%d,socket:%d]",core_list[10],socket_list[10]); ProcNames[10]->setText(tr (processor_str)); snprintf(processor_str, 100, "Core-12 [id:%d,socket:%d]",core_list[11],socket_list[11]); ProcNames[11]->setText(tr (processor_str)); //Have to make sure that the constructor is being called correct. //the below code logic is that if a core goes offline, call the constructor //so as to replot all the widgets. /* printf("Number of Cores %d\n",numCPUs); if(numCPUs != curr_numCPUs){ curr_numCPUs = numCPUs; printf("Number of Cores changed\n"); MyWidget (0); }*/ // printf("UpdateWidget: Num Processors %d\n",numCPUs); int i; char val2set[100]; for (i = 0; i < (int)numCPUs; i++) { snprintf (val2set, 100, "%0.2f Mhz", mythread->FREQ[i]); Freq_[i]->setText (val2set); } for (i = 0; i < (int)numCPUs; i++) { C0_l[i]->setValue (mythread->C0_TIME[i] * 100); C1_l[i]->setValue (mythread->C1_TIME[i] * 100); C3_l[i]->setValue (mythread->C3_TIME[i] * 100); C6_l[i]->setValue (mythread->C6_TIME[i] * 100); } float Max_Freq_socket0 = 0; float Max_Freq_socket1 = 0; int num_socket0_cpus, num_socket1_cpus; for (i = 0; i < (int)numCPUs; i++) { if ( (mythread->FREQ[i] > Max_Freq_socket0) && (!isnan(mythread->FREQ[i])) && (!isinf(mythread->FREQ[i])) && (socket_list[i] == socket_0.socket_num) ) { Max_Freq_socket0 = mythread->FREQ[i]; num_socket0_cpus++; } if ( (mythread->FREQ[i] > Max_Freq_socket1) && (!isnan(mythread->FREQ[i])) && (!isinf(mythread->FREQ[i])) && (socket_list[i] == socket_1.socket_num) ) { Max_Freq_socket1 = mythread->FREQ[i]; num_socket1_cpus++; } } if (socket_0.num_physical_cores > 0) { StatusMessage0->setText ("Socket[0] Freq:"); snprintf (val2set, 100, "%0.2f Mhz", Max_Freq_socket0); Curr_Freq0->setText (val2set); } if (socket_1.num_physical_cores > 0) { StatusMessage1->setText ("Socket[1] Freq:"); snprintf (val2set, 100, "%0.2f Mhz", Max_Freq_socket1); Curr_Freq1->setText (val2set); } } int main (int argc, char *argv[]) { char hostname[1024]; hostname[1023] = '\0'; gethostname(hostname, 1023); QApplication app (argc, argv); char str_display[1050]; snprintf(str_display, 1050, "i7z @ %s", hostname); MyWidget i7z_widget; i7z_widget.setWindowTitle(str_display); i7z_widget.show (); return app.exec (); } #include "i7z_GUI.moc" i7z-0.27.2/GUI/compile_me.sh0000644000175000017500000000011612023553432013771 0ustar abhiabhi#make clean #rm Makefile #qmake-qt4 -project #qmake-qt4 qmake make clean make i7z-0.27.2/GUI/i7z_GUI.pro0000644000175000017500000000114212023553432013263 0ustar abhiabhi###################################################################### # Automatically generated by qmake (2.01a) Tue Jan 26 22:31:53 2010 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . CONFIG += debug CFLAGS += #QMAKE_*FLAGS are where the gcc flags should be passed CXXFLAGS += QMAKE_CFLAGS += -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves QMAKE_CXXFLAGS += -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves # Input SOURCES += i7z_GUI.cpp i7z-0.27.2/GUI/README_GUI.txt0000644000175000017500000000054412023553432013533 0ustar abhiabhiBy Abhishek Jaiantilal Under GPL v2 #to make the gui working you will need qt4 installed. libqt4-dev, qmake-qt4 should be enough i think running the Makefile should be enough svn-r43 Wworks for Dual Socket Boards but wont work if core is taken offline while the tool is running. Right way of compiling is the following 3 steps qmake make clean makei7z-0.27.2/GUI/Makefile0000644000175000017500000001513712023553432012775 0ustar abhiabhi############################################################################# # Makefile for building: i7z_GUI # Generated by qmake (2.01a) (Qt 4.7.4) on: Mon Mar 12 16:54:28 2012 # Project: i7z_GUI.pro # Template: app # Command: /usr/bin/qmake -o Makefile i7z_GUI.pro ############################################################################# ####### Compiler, tools and options CC = gcc CXX = g++ DEFINES = -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED CFLAGS = -m64 -pipe -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves -g -Wall -W -D_REENTRANT $(DEFINES) CXXFLAGS = -m64 -pipe -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves -g -Wall -W -D_REENTRANT $(DEFINES) INCPATH = -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. LINK = g++ LFLAGS = -m64 LIBS = $(SUBLIBS) -L/usr/lib -lQtGui -lQtCore -lpthread AR = ar cqs RANLIB = QMAKE = /usr/bin/qmake TAR = tar -cf COMPRESS = gzip -9f COPY = cp -f SED = sed COPY_FILE = $(COPY) COPY_DIR = $(COPY) -r STRIP = strip INSTALL_FILE = install -m 644 -p INSTALL_DIR = $(COPY_DIR) INSTALL_PROGRAM = install -m 755 -p DEL_FILE = rm -f SYMLINK = ln -f -s DEL_DIR = rmdir MOVE = mv -f CHK_DIR_EXISTS= test -d MKDIR = mkdir -p ####### Output directory OBJECTS_DIR = ./ ####### Files SOURCES = i7z_GUI.cpp OBJECTS = i7z_GUI.o DIST = /usr/share/qt4/mkspecs/common/g++.conf \ /usr/share/qt4/mkspecs/common/unix.conf \ /usr/share/qt4/mkspecs/common/linux.conf \ /usr/share/qt4/mkspecs/qconfig.pri \ /usr/share/qt4/mkspecs/features/qt_functions.prf \ /usr/share/qt4/mkspecs/features/qt_config.prf \ /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ /usr/share/qt4/mkspecs/features/default_pre.prf \ /usr/share/qt4/mkspecs/features/debug.prf \ /usr/share/qt4/mkspecs/features/default_post.prf \ /usr/share/qt4/mkspecs/features/warn_on.prf \ /usr/share/qt4/mkspecs/features/qt.prf \ /usr/share/qt4/mkspecs/features/unix/thread.prf \ /usr/share/qt4/mkspecs/features/moc.prf \ /usr/share/qt4/mkspecs/features/resources.prf \ /usr/share/qt4/mkspecs/features/uic.prf \ /usr/share/qt4/mkspecs/features/yacc.prf \ /usr/share/qt4/mkspecs/features/lex.prf \ /usr/share/qt4/mkspecs/features/include_source_dir.prf \ i7z_GUI.pro QMAKE_TARGET = i7z_GUI DESTDIR = TARGET = i7z_GUI first: all ####### Implicit rules .SUFFIXES: .o .c .cpp .cc .cxx .C .cpp.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .cxx.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .C.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" .c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" ####### Build rules all: Makefile $(TARGET) $(TARGET): $(OBJECTS) $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) Makefile: i7z_GUI.pro /usr/share/qt4/mkspecs/linux-g++-64/qmake.conf /usr/share/qt4/mkspecs/common/g++.conf \ /usr/share/qt4/mkspecs/common/unix.conf \ /usr/share/qt4/mkspecs/common/linux.conf \ /usr/share/qt4/mkspecs/qconfig.pri \ /usr/share/qt4/mkspecs/features/qt_functions.prf \ /usr/share/qt4/mkspecs/features/qt_config.prf \ /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ /usr/share/qt4/mkspecs/features/default_pre.prf \ /usr/share/qt4/mkspecs/features/debug.prf \ /usr/share/qt4/mkspecs/features/default_post.prf \ /usr/share/qt4/mkspecs/features/warn_on.prf \ /usr/share/qt4/mkspecs/features/qt.prf \ /usr/share/qt4/mkspecs/features/unix/thread.prf \ /usr/share/qt4/mkspecs/features/moc.prf \ /usr/share/qt4/mkspecs/features/resources.prf \ /usr/share/qt4/mkspecs/features/uic.prf \ /usr/share/qt4/mkspecs/features/yacc.prf \ /usr/share/qt4/mkspecs/features/lex.prf \ /usr/share/qt4/mkspecs/features/include_source_dir.prf \ /usr/lib/libQtGui.prl \ /usr/lib/libQtCore.prl $(QMAKE) -o Makefile i7z_GUI.pro /usr/share/qt4/mkspecs/common/g++.conf: /usr/share/qt4/mkspecs/common/unix.conf: /usr/share/qt4/mkspecs/common/linux.conf: /usr/share/qt4/mkspecs/qconfig.pri: /usr/share/qt4/mkspecs/features/qt_functions.prf: /usr/share/qt4/mkspecs/features/qt_config.prf: /usr/share/qt4/mkspecs/features/exclusive_builds.prf: /usr/share/qt4/mkspecs/features/default_pre.prf: /usr/share/qt4/mkspecs/features/debug.prf: /usr/share/qt4/mkspecs/features/default_post.prf: /usr/share/qt4/mkspecs/features/warn_on.prf: /usr/share/qt4/mkspecs/features/qt.prf: /usr/share/qt4/mkspecs/features/unix/thread.prf: /usr/share/qt4/mkspecs/features/moc.prf: /usr/share/qt4/mkspecs/features/resources.prf: /usr/share/qt4/mkspecs/features/uic.prf: /usr/share/qt4/mkspecs/features/yacc.prf: /usr/share/qt4/mkspecs/features/lex.prf: /usr/share/qt4/mkspecs/features/include_source_dir.prf: /usr/lib/libQtGui.prl: /usr/lib/libQtCore.prl: qmake: FORCE @$(QMAKE) -o Makefile i7z_GUI.pro dist: @$(CHK_DIR_EXISTS) .tmp/i7z_GUI1.0.0 || $(MKDIR) .tmp/i7z_GUI1.0.0 $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/i7z_GUI1.0.0/ && $(COPY_FILE) --parents i7z_GUI.cpp .tmp/i7z_GUI1.0.0/ && (cd `dirname .tmp/i7z_GUI1.0.0` && $(TAR) i7z_GUI1.0.0.tar i7z_GUI1.0.0 && $(COMPRESS) i7z_GUI1.0.0.tar) && $(MOVE) `dirname .tmp/i7z_GUI1.0.0`/i7z_GUI1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/i7z_GUI1.0.0 clean:compiler_clean -$(DEL_FILE) $(OBJECTS) -$(DEL_FILE) *~ core *.core ####### Sub-libraries distclean: clean -$(DEL_FILE) $(TARGET) -$(DEL_FILE) Makefile check: first mocclean: compiler_moc_header_clean compiler_moc_source_clean mocables: compiler_moc_header_make_all compiler_moc_source_make_all compiler_moc_header_make_all: compiler_moc_header_clean: compiler_rcc_make_all: compiler_rcc_clean: compiler_image_collection_make_all: qmake_image_collection.cpp compiler_image_collection_clean: -$(DEL_FILE) qmake_image_collection.cpp compiler_moc_source_make_all: i7z_GUI.moc compiler_moc_source_clean: -$(DEL_FILE) i7z_GUI.moc i7z_GUI.moc: ../helper_functions.c \ ../i7z.h \ i7z_GUI.cpp /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) i7z_GUI.cpp -o i7z_GUI.moc compiler_uic_make_all: compiler_uic_clean: compiler_yacc_decl_make_all: compiler_yacc_decl_clean: compiler_yacc_impl_make_all: compiler_yacc_impl_clean: compiler_lex_make_all: compiler_lex_clean: compiler_clean: compiler_moc_source_clean ####### Compile i7z_GUI.o: i7z_GUI.cpp ../helper_functions.c \ ../i7z.h \ i7z_GUI.moc $(CXX) -c $(CXXFLAGS) $(INCPATH) -o i7z_GUI.o i7z_GUI.cpp ####### Install install: FORCE uninstall: FORCE FORCE: i7z-0.27.2/GUI/i7z_GUI.moc0000644000175000017500000000433512023553432013250 0ustar abhiabhi/**************************************************************************** ** Meta object code from reading C++ file 'i7z_GUI.cpp' ** ** Created: Mon Mar 12 16:54:28 2012 ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.4) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'i7z_GUI.cpp' doesn't include ." #elif Q_MOC_OUTPUT_REVISION != 62 #error "This file was generated using the moc from 4.7.4. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE static const uint qt_meta_data_MyWidget[] = { // content: 5, // revision 0, // classname 0, 0, // classinfo 1, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // slots: signature, parameters, type, tag, flags 10, 9, 9, 9, 0x08, 0 // eod }; static const char qt_meta_stringdata_MyWidget[] = { "MyWidget\0\0UpdateWidget()\0" }; const QMetaObject MyWidget::staticMetaObject = { { &QWidget::staticMetaObject, qt_meta_stringdata_MyWidget, qt_meta_data_MyWidget, 0 } }; #ifdef Q_NO_DATA_RELOCATION const QMetaObject &MyWidget::getStaticMetaObject() { return staticMetaObject; } #endif //Q_NO_DATA_RELOCATION const QMetaObject *MyWidget::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; } void *MyWidget::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_MyWidget)) return static_cast(const_cast< MyWidget*>(this)); return QWidget::qt_metacast(_clname); } int MyWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QWidget::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: UpdateWidget(); break; default: ; } _id -= 1; } return _id; } QT_END_MOC_NAMESPACE i7z-0.27.2/COPYING0000644000175000017500000004325412023553432011745 0ustar abhiabhi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. i7z-0.27.2/i7z_Single_Socket.c0000644000175000017500000014452412023553432014402 0ustar abhiabhi//i7z_Single_Socket.c /* ----------------------------------------------------------------------- * * * Copyright 2010 Abhishek Jaiantilal * * Under GPL v2 * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "i7z.h" #define U_L_I unsigned long int #define U_L_L_I unsigned long long int #define numCPUs_max MAX_PROCESSORS extern int socket_0_num, socket_1_num; extern bool E7_mp_present; extern int numPhysicalCores, numLogicalCores; extern double TRUE_CPU_FREQ; int Read_Thermal_Status_CPU(int cpu_num); extern struct program_options prog_options; extern FILE *fp_log_file_freq; struct timespec global_ts; extern char* CPU_FREQUENCY_LOGGING_FILE_single; extern char* CPU_FREQUENCY_LOGGING_FILE_dual; extern bool use_ncurses; void logCpuFreq_single_ts( struct timespec*); void print_i7z_socket_single(struct cpu_socket_info socket_0, int printw_offset, int PLATFORM_INFO_MSR, int PLATFORM_INFO_MSR_high, int PLATFORM_INFO_MSR_low, int* online_cpus, double cpu_freq_cpuinfo, struct timespec one_second_sleep, char TURBO_MODE, char* HT_ON_str, int* kk_1, U_L_L_I * old_val_CORE, U_L_L_I * old_val_REF, U_L_L_I * old_val_C3, U_L_L_I * old_val_C6, U_L_L_I * old_val_C7, U_L_L_I * old_TSC, int estimated_mhz, U_L_L_I * new_val_CORE, U_L_L_I * new_val_REF, U_L_L_I * new_val_C3, U_L_L_I * new_val_C6, U_L_L_I * new_val_C7, U_L_L_I * new_TSC, double* _FREQ, double* _MULT, long double * C0_time, long double * C1_time, long double * C3_time, long double * C6_time, long double * C7_time, struct timeval* tvstart, struct timeval* tvstop, int *max_observed_cpu); void print_i7z_single (); int Single_Socket () { //zero up the file before doing anything if(prog_options.logging!=0){ fp_log_file_freq = fopen(CPU_FREQUENCY_LOGGING_FILE_single,"w"); fclose(fp_log_file_freq); } printf ("i7z DEBUG: In i7z Single_Socket()\n"); if (prog_options.i7_version.sandy_bridge) printf ("i7z DEBUG: guessing Sandy Bridge\n"); else printf ("i7z DEBUG: guessing Nehalem\n"); sleep (3); if (use_ncurses){ //int row, col; /* to store the number of rows and * * the number of colums of the screen * * for NCURSES */ //Setup stuff for ncurses initscr (); /* start the curses mode */ start_color (); //getmaxyx (stdscr, row, col); /* get the number of rows and columns */ refresh (); //Setup for ncurses completed } print_i7z_single(); exit (0); return (1); } void print_i7z_socket_single(struct cpu_socket_info socket_0, int printw_offset, int PLATFORM_INFO_MSR, int PLATFORM_INFO_MSR_high, int PLATFORM_INFO_MSR_low, int* online_cpus, double cpu_freq_cpuinfo, struct timespec one_second_sleep, char TURBO_MODE, char* HT_ON_str, int* kk_1, U_L_L_I * old_val_CORE, U_L_L_I * old_val_REF, U_L_L_I * old_val_C3, U_L_L_I * old_val_C6, U_L_L_I * old_val_C7, U_L_L_I * old_TSC, int estimated_mhz, U_L_L_I * new_val_CORE, U_L_L_I * new_val_REF, U_L_L_I * new_val_C3, U_L_L_I * new_val_C6, U_L_L_I * new_val_C7, U_L_L_I * new_TSC, double* _FREQ, double* _MULT, long double * C0_time, long double * C1_time, long double * C3_time, long double * C6_time, long double * C7_time, struct timeval* tvstart, struct timeval* tvstop, int *max_observed_cpu) { int numPhysicalCores, numLogicalCores; double TRUE_CPU_FREQ; //Print a slew of information on the ncurses window mvprintw (0, 0, "Cpu speed from cpuinfo %0.2fMhz\n", cpu_freq_cpuinfo); mvprintw (1, 0, "cpuinfo might be wrong if cpufreq is enabled. To guess correctly try estimating via tsc\n"); mvprintw (2, 0, "Linux's inbuilt cpu_khz code emulated now\n\n"); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); mvprintw (3, 0, "True Frequency (without accounting Turbo) %0.0f MHz\n", cpu_freq_cpuinfo); int i, ii; //int k; int CPU_NUM; int* core_list; unsigned long int IA32_MPERF, IA32_APERF; int CPU_Multiplier, error_indx; unsigned long long int CPU_CLK_UNHALTED_CORE, CPU_CLK_UNHALTED_REF, CPU_CLK_C3, CPU_CLK_C6, CPU_CLK_C1, CPU_CLK_C7; //current blck value float BLCK; char print_core[32]; long double c1_time; //use this variable to monitor the max number of cores ever online *max_observed_cpu = (socket_0.max_cpu > *max_observed_cpu)? socket_0.max_cpu: *max_observed_cpu; int core_list_size_phy, core_list_size_log; if (socket_0.max_cpu > 0) { //set the variable print_core to 0, use it to check if a core is online and doesnt //have any garbage values memset(print_core, 0, 6*sizeof(char)); //We just need one CPU (we use Core-1) to figure out the multiplier and the bus clock freq. //multiplier doesnt automatically include turbo //note turbo is not guaranteed, only promised //So this msr will only reflect the actual multiplier, rest has to be figured out //Now get all the information about the socket from the structure CPU_NUM = socket_0.processor_num[0]; core_list = socket_0.processor_num; core_list_size_phy = socket_0.num_physical_cores; core_list_size_log = socket_0.num_logical_cores; /*if (CPU_NUM == -1) { sleep (1); //sleep for a bit hoping that the offline socket becomes online continue; }*/ //number of CPUs is as told via cpuinfo int numCPUs = socket_0.num_physical_cores; CPU_Multiplier = get_msr_value (CPU_NUM, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Blck is basically the true speed divided by the multiplier BLCK = cpu_freq_cpuinfo / CPU_Multiplier; //Use Core-1 as the one to check for the turbo limit //Core number shouldnt matter //bits from 0-63 in this store the various maximum turbo limits int MSR_TURBO_RATIO_LIMIT = 429; // 3B defines till Max 4 Core and the rest bit values from 32:63 were reserved. int MAX_TURBO_1C=0, MAX_TURBO_2C=0, MAX_TURBO_3C=0, MAX_TURBO_4C=0, MAX_TURBO_5C=0, MAX_TURBO_6C=0; if ( E7_mp_present){ //e7 mp dont have 429 register so dont read the register. } else { //Bits:0-7 - core1 MAX_TURBO_1C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:15-8 - core2 MAX_TURBO_2C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 15, 8, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:23-16 - core3 MAX_TURBO_3C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 23, 16, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:31-24 - core4 MAX_TURBO_4C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 31, 24, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //gulftown/Hexacore support //technically these should be the bits to get for core 5,6 //Bits:39-32 - core4 MAX_TURBO_5C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 39, 32, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Bits:47-40 - core4 MAX_TURBO_6C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 47, 40, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); } //fflush (stdout); //sleep (1); char string_ptr1[200], string_ptr2[200]; int IA32_PERF_GLOBAL_CTRL = 911; //38F int IA32_PERF_GLOBAL_CTRL_Value; IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); int IA32_FIXED_CTR_CTL = 909; //38D int IA32_FIXED_CTR_CTL_Value; IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); CPU_CLK_UNHALTED_CORE = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); CPU_CLK_UNHALTED_REF = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); //SLEEP FOR 1 SECOND (500ms is also alright) nanosleep (&one_second_sleep, NULL); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx) - IA32_MPERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx) - IA32_APERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); RETURN_IF_TRUE(online_cpus[0]==-1); mvprintw (4 + printw_offset, 0," CPU Multiplier %dx || Bus clock frequency (BCLK) %0.2f MHz \n", CPU_Multiplier, BLCK); if (numCPUs <= 0) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 0 cores is"); sprintf (string_ptr2, " %dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C); } if (numCPUs >= 1 && numCPUs < 4) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2 Cores is"); sprintf (string_ptr2, " "); } if (numCPUs >= 2 && numCPUs < 6) { sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2/3/4 Cores is"); sprintf (string_ptr2, " %dx/%dx/%dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C, MAX_TURBO_3C, MAX_TURBO_4C); } if (numCPUs >= 2 && numCPUs >= 6) { // Gulftown 6-cores, Nehalem-EX sprintf (string_ptr1, " Max TURBO Multiplier (if Enabled) with 1/2/3/4/5/6 Cores is"); sprintf (string_ptr2, " %dx/%dx/%dx/%dx/%dx/%dx ", MAX_TURBO_1C, MAX_TURBO_2C, MAX_TURBO_3C, MAX_TURBO_4C, MAX_TURBO_5C, MAX_TURBO_6C); } numCPUs = core_list_size_phy; numPhysicalCores = core_list_size_phy; numLogicalCores = core_list_size_log; //if (socket_0.socket_num == 0) { mvprintw (19, 0, "C0 = Processor running without halting"); mvprintw (20, 0, "C1 = Processor running with halts (States >C0 are power saver)"); mvprintw (21, 0, "C3 = Cores running with PLL turned off and core cache turned off"); mvprintw (22, 0, "C6 = Everything in C3 + core state saved to last level cache"); mvprintw (23, 0, " Above values in table are in percentage over the last 1 sec"); // mvprintw (24, 0, "Total Logical Cores: [%d], Total Physical Cores: [%d] \n", numLogicalCores, numPhysicalCores); mvprintw (24, 0, "[core-id] refers to core-id number in /proc/cpuinfo"); mvprintw (25, 0, "'Garbage Values' message printed when garbage values are read"); mvprintw (26, 0, " Ctrl+C to exit"); //} mvprintw (6 + printw_offset, 0, "Socket [%d] - [physical cores=%d, logical cores=%d, max online cores ever=%d] \n", socket_0.socket_num, numPhysicalCores, numLogicalCores,*max_observed_cpu); mvprintw (9 + printw_offset, 0, "%s %s\n", string_ptr1, string_ptr2); if (TURBO_MODE == 1) { mvprintw (7 + printw_offset, 0, " TURBO ENABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier + 1); mvprintw (8 + printw_offset, 0, " Max Frequency without considering Turbo %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier + 1); } else { mvprintw (7 + printw_offset, 0, " TURBO DISABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier); mvprintw (8 + printw_offset, 0," Max Frequency without considering Turbo %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier); } //Primarily for 32-bit users, found that after sometimes the counters loopback, so inorder //to prevent loopback, reset the counters back to 0 after 10 iterations roughly 10 secs if (*kk_1 > 10) { *kk_1 = 0; for (i = 0; i < numCPUs; i++) { //Set up the performance counters and then start reading from them assert(i < MAX_SK_PROCESSORS); CPU_NUM = core_list[i]; ii = core_list[i]; assert(i < MAX_PROCESSORS); //online_cpus[i] assert(ii < numCPUs_max); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); set_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 0x700000003LLU); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); set_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 819); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); old_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); if(prog_options.i7_version.sandy_bridge){ //table b-20 in 325384 and only for sandy bridge old_val_C7[ii] = get_msr_value (CPU_NUM, 1022, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); } old_TSC[ii] = rdtsc (); } } (*kk_1)++; nanosleep (&one_second_sleep, NULL); if(prog_options.i7_version.sandy_bridge){ mvprintw (11 + printw_offset, 0, "\tCore [core-id] :Actual Freq (Mult.)\t C0%% Halt(C1)%% C3 %% C6 %% C7 %% Temp\n"); }else{ mvprintw (11 + printw_offset, 0, "\tCore [core-id] :Actual Freq (Mult.)\t C0%% Halt(C1)%% C3 %% C6 %% Temp\n"); } //estimate the CPU speed estimated_mhz = estimate_MHz (); for (i = 0; i < numCPUs; i++) { //read from the performance counters //things like halted unhalted core cycles assert(i < MAX_SK_PROCESSORS); CPU_NUM = core_list[i]; ii = core_list[i]; assert(i < MAX_PROCESSORS); //online_cpus[i] assert(ii < numCPUs_max); new_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); if(prog_options.i7_version.sandy_bridge){ new_val_C7[ii] = get_msr_value (CPU_NUM, 1022, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); } new_TSC[ii] = rdtsc (); if (old_val_CORE[ii] > new_val_CORE[ii]) { //handle overflow CPU_CLK_UNHALTED_CORE = (UINT64_MAX - old_val_CORE[ii]) + new_val_CORE[ii]; } else { CPU_CLK_UNHALTED_CORE = new_val_CORE[ii] - old_val_CORE[ii]; } //number of TSC cycles while its in halted state if ((new_TSC[ii] - old_TSC[ii]) < CPU_CLK_UNHALTED_CORE) { CPU_CLK_C1 = 0; } else { CPU_CLK_C1 = ((new_TSC[ii] - old_TSC[ii]) - CPU_CLK_UNHALTED_CORE); } if (old_val_REF[ii] > new_val_REF[ii]) { //handle overflow CPU_CLK_UNHALTED_REF = (UINT64_MAX - old_val_REF[ii]) + new_val_REF[ii]; //3.40282366921e38 } else { CPU_CLK_UNHALTED_REF = new_val_REF[ii] - old_val_REF[ii]; } if (old_val_C3[ii] > new_val_C3[ii]) { //handle overflow CPU_CLK_C3 = (UINT64_MAX - old_val_C3[ii]) + new_val_C3[ii]; } else { CPU_CLK_C3 = new_val_C3[ii] - old_val_C3[ii]; } if (old_val_C6[ii] > new_val_C6[ii]) { //handle overflow CPU_CLK_C6 = (UINT64_MAX - old_val_C6[ii]) + new_val_C6[ii]; } else { CPU_CLK_C6 = new_val_C6[ii] - old_val_C6[ii]; } if(prog_options.i7_version.sandy_bridge){ if (old_val_C7[ii] > new_val_C7[ii]) { //handle overflow CPU_CLK_C7 = (UINT64_MAX - old_val_C7[ii]) + new_val_C7[ii]; } else { CPU_CLK_C7 = new_val_C7[ii] - old_val_C7[ii]; } } _FREQ[ii] = THRESHOLD_BETWEEN_0_6000(estimated_mhz * ((long double) CPU_CLK_UNHALTED_CORE / (long double) CPU_CLK_UNHALTED_REF)); _MULT[ii] = _FREQ[ii] / BLCK; C0_time[ii] = ((long double) CPU_CLK_UNHALTED_REF / (long double) (new_TSC[ii] - old_TSC[ii])); C1_time[ii] = ((long double) CPU_CLK_C1 / (long double) (new_TSC[ii] - old_TSC[ii])); C3_time[ii] = ((long double) CPU_CLK_C3 / (long double) (new_TSC[ii] - old_TSC[ii])); C6_time[ii] = ((long double) CPU_CLK_C6 / (long double) (new_TSC[ii] - old_TSC[ii])); if(prog_options.i7_version.sandy_bridge){ C7_time[ii] = ((long double) CPU_CLK_C7 / (long double) (new_TSC[ii] - old_TSC[ii])); } if (C0_time[ii] < 1e-2) { if (C0_time[ii] > 1e-4) { C0_time[ii] = 0.01; } else { C0_time[ii] = 0; } } if (C1_time[ii] < 1e-2) { if (C1_time[ii] > 1e-4) { C1_time[ii] = 0.01; } else { C1_time[ii] = 0; } } if (C3_time[ii] < 1e-2) { if (C3_time[ii] > 1e-4) { C3_time[ii] = 0.01; } else { C3_time[ii] = 0; } } if (C6_time[ii] < 1e-2) { if (C6_time[ii] > 1e-4) { C6_time[ii] = 0.01; } else { C6_time[ii] = 0; } } if(prog_options.i7_version.sandy_bridge){ if (C7_time[ii] < 1e-2) { if (C7_time[ii] > 1e-4) { C7_time[ii] = 0.01; } else { C7_time[ii] = 0; } } } } //CHECK IF ALL COUNTERS ARE CORRECT AND NO GARBAGE VALUES ARE PRESENT //If there is any garbage values set print_core[i] to 0 for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if(prog_options.i7_version.sandy_bridge){ if ( !IS_THIS_BETWEEN_0_100(C0_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100) || !IS_THIS_BETWEEN_0_100(C3_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C6_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C7_time[i] * 100) || isinf(_FREQ[i]) ) print_core[ii]=0; else print_core[ii]=1; }else{ if ( !IS_THIS_BETWEEN_0_100(C0_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100) || !IS_THIS_BETWEEN_0_100(C3_time[i] * 100) || !IS_THIS_BETWEEN_0_100(C6_time[i] * 100) || isinf(_FREQ[i]) ) print_core[ii]=0; else print_core[ii]=1; } } //Now print the information about the cores. Print garbage values message if there is garbage for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if(prog_options.i7_version.sandy_bridge){ //there is a bit of leeway to be had as the total counts might deviate //if this happens c1_time might be negative so just adjust so that it is thresholded to 0 c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i] + C7_time[i]) * 100; if (!isnan(c1_time) && !isinf(c1_time)) { if (c1_time <= 0) { c1_time=0; } } if (print_core[ii]) mvprintw (12 + ii + printw_offset, 0, "\tCore %d [%d]:\t %0.2f (%.2fx)\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%d\n", ii + 1, core_list[ii], _FREQ[i], _MULT[i], THRESHOLD_BETWEEN_0_100(C0_time[i] * 100), THRESHOLD_BETWEEN_0_100(c1_time), THRESHOLD_BETWEEN_0_100(C3_time[i] * 100), THRESHOLD_BETWEEN_0_100(C6_time[i] * 100),THRESHOLD_BETWEEN_0_100(C7_time[i] * 100), Read_Thermal_Status_CPU(core_list[ii])); //C0_time[i]*100+C1_time[i]*100 around 100 else mvprintw (12 + ii + printw_offset, 0, "\tCore %d [%d]:\t Garbage Values\n", ii + 1, core_list[ii]); }else{ //there is a bit of leeway to be had as the total counts might deviate //if this happens c1_time might be negative so just adjust so that it is thresholded to 0 c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i]) * 100; if (!isnan(c1_time) && !isinf(c1_time)) { if (c1_time <= 0) { c1_time=0; } } if (print_core[ii]) mvprintw (12 + ii + printw_offset, 0, "\tCore %d [%d]:\t %0.2f (%.2fx)\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%d\n", ii + 1, core_list[ii], _FREQ[i], _MULT[i], THRESHOLD_BETWEEN_0_100(C0_time[i] * 100), THRESHOLD_BETWEEN_0_100(c1_time), THRESHOLD_BETWEEN_0_100(C3_time[i] * 100), THRESHOLD_BETWEEN_0_100(C6_time[i] * 100),Read_Thermal_Status_CPU(core_list[ii])); //C0_time[i]*100+C1_time[i]*100 around 100 else mvprintw (12 + ii + printw_offset, 0, "\tCore %d [%d]:\t Garbage Values\n", ii + 1, core_list[ii]); } } /*k=0; for (ii = 00; ii < *max_observed_cpu; ii++) { if (in_core_list(ii,core_list)){ continue; }else{ mvprintw (12 + k + numCPUs + printw_offset, 0, "\tProcessor %d [%d]: OFFLINE\n", k + numCPUs + 1, ii); } k++; }*/ //FOR THE REST OF THE CORES (i.e. the offline cores+non-present cores=6 ) //I have space allocated for 6 cores to be printed per socket so from all the present cores //till 6 print a blank line //for(ii=*max_observed_cpu; ii<6; ii++) for (ii = numCPUs; ii<6; ii++) mvprintw (12 + ii + printw_offset, 0, "\n"); TRUE_CPU_FREQ = 0; logOpenFile_single(); //time_t time_to_save; //logCpuFreq_single_d(time(&time_to_save)); clock_gettime(CLOCK_REALTIME, &global_ts); logCpuFreq_single_ts( &global_ts); logCpuCstates_single_ts( &global_ts); for (ii = 0; ii < numCPUs; ii++) { assert(ii < MAX_SK_PROCESSORS); i = core_list[ii]; if ( (_FREQ[i] > TRUE_CPU_FREQ) && (print_core[ii]) && !isinf(_FREQ[i]) ) { TRUE_CPU_FREQ = _FREQ[i]; } if ( (print_core[ii]) && !isinf(_FREQ[i]) ) { logCpuFreq_single(_FREQ[i]); } logCpuCstates_single_c(" ["); logCpuCstates_single((float)THRESHOLD_BETWEEN_0_100(C0_time[i] * 100)); logCpuCstates_single_c(","); c1_time = C1_time[i] * 100 - (C3_time[i] + C6_time[i] + C7_time[i]) * 100; logCpuCstates_single((float)THRESHOLD_BETWEEN_0_100(c1_time)); logCpuCstates_single_c(","); logCpuCstates_single((float)THRESHOLD_BETWEEN_0_100(C3_time[i] * 100)); logCpuCstates_single_c(","); logCpuCstates_single((float)THRESHOLD_BETWEEN_0_100(C6_time[i] * 100)); if(prog_options.i7_version.sandy_bridge){ logCpuCstates_single_c(","); logCpuCstates_single((float)THRESHOLD_BETWEEN_0_100(C7_time[i] * 100)); } logCpuCstates_single_c("]\t"); } // logCpuCstates_single_c("\n"); logCloseFile_single(); mvprintw (10 + printw_offset, 0, " Real Current Frequency %0.2f MHz [%0.2f x %0.2f] (Max of below)\n", TRUE_CPU_FREQ, BLCK, TRUE_CPU_FREQ/BLCK); refresh (); //shift the new values to the old counter values //so that the next time we use those to find the difference memcpy (old_val_CORE, new_val_CORE, sizeof (*old_val_CORE) * numCPUs); memcpy (old_val_REF, new_val_REF, sizeof (*old_val_REF) * numCPUs); memcpy (old_val_C3, new_val_C3, sizeof (*old_val_C3) * numCPUs); memcpy (old_val_C6, new_val_C6, sizeof (*old_val_C6) * numCPUs); if(prog_options.i7_version.sandy_bridge){ memcpy (old_val_C7, new_val_C7, sizeof (*old_val_C7) * numCPUs); } memcpy (tvstart, tvstop, sizeof (*tvstart) * numCPUs); memcpy (old_TSC, new_TSC, sizeof (*old_TSC) * numCPUs); } else { // If all the cores in the socket go offline, just erase the whole screen //WELL for single socket machine this code will never be executed. lol //atleast 1 core will be online so ... //for (ii = 0 ; ii<14; ii++) // mvprintw (3 + ii + printw_offset, 0, "Ending up here\n"); //print_socket_information(&socket_0); } } void print_i7z_single () { struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); // print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); // print_socket_information(&socket_0); // print_socket_information(&socket_1); int printw_offset = (0) * 14; //Make an array size max 8 (to accomdate Nehalem-EXEX -lol) to store the core-num that are candidates for a given socket //removing it from here as it is already allocated in the function //int *core_list, core_list_size_phy, core_list_size_log; //iterator int i; //turbo_mode enabled/disabled flag char TURBO_MODE; double cpu_freq_cpuinfo; cpu_freq_cpuinfo = cpufreq_info (); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); //Print a slew of information on the ncurses window //I already print that in the loop so.. mvprintw (0, 0, "WAIT .... "); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); mvprintw (3, 0, "True Frequency (without accounting Turbo) %0.0f MHz\n", cpu_freq_cpuinfo); //MSR number and hi:low bit of that MSR //This msr contains a lot of stuff, per socket wise //one can pass any core number and then get in multiplier etc int PLATFORM_INFO_MSR = 206; //CE 15:8 int PLATFORM_INFO_MSR_low = 8; int PLATFORM_INFO_MSR_high = 15; unsigned long long int old_val_CORE[2][numCPUs_max], new_val_CORE[2][numCPUs_max]; unsigned long long int old_val_REF[2][numCPUs_max], new_val_REF[2][numCPUs_max]; unsigned long long int old_val_C3[2][numCPUs_max], new_val_C3[2][numCPUs_max]; unsigned long long int old_val_C6[2][numCPUs_max], new_val_C6[2][numCPUs_max]; unsigned long long int old_val_C7[2][numCPUs_max], new_val_C7[2][numCPUs_max]; unsigned long long int old_TSC[2][numCPUs_max], new_TSC[2][numCPUs_max]; long double C0_time[2][numCPUs_max], C1_time[2][numCPUs_max], C3_time[2][numCPUs_max], C6_time[2][numCPUs_max], C7_time[2][numCPUs_max]; double _FREQ[2][numCPUs_max], _MULT[2][numCPUs_max]; struct timeval tvstart[2][numCPUs_max], tvstop[2][numCPUs_max]; struct timespec one_second_sleep; one_second_sleep.tv_sec = 0; one_second_sleep.tv_nsec = 499999999; // 500msec //Get turbo mode status by reading msr within turbo_status TURBO_MODE = turbo_status (); //Flags and other things about HT. int HT_ON; char HT_ON_str[30]; int kk_1 = 11; //below variables is used to monitor if any cores went offline etc. int online_cpus[MAX_PROCESSORS]; //Max 2 x Nehalem-EX with total 32 threads double estimated_mhz=0; int socket_num; //below variables stores how many cpus were observed till date for the socket int max_cpus_observed=0; for (;;) { construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); //HT enabled if num logical > num physical cores if (chi.HT==1) { strncpy (HT_ON_str, "Hyper Threading ON\0", 30); HT_ON = 1; } else { strncpy (HT_ON_str, "Hyper Threading OFF\0", 30); HT_ON = 0; } refresh (); SET_ONLINE_ARRAY_PLUS1(online_cpus) //In the function calls below socket_num is set to the socket to print for //printw_offset is the offset gap between the printing of the two sockets //kk_1 and kk_2 are the variables that have to be set, i have to use them internally //so in future if there are more sockets to be printed, add more kk_* socket_num=0; printw_offset=0; //printf("socket0 max cpu %d\n",socket_0.max_cpu); //printf("socket1 max cpu %d\n",socket_0.max_cpu); //below code in (else case) is to handle when for 2 sockets system, cpu1 is populated and cpu0 is empty. //single socket code but in an intelligent manner and not assuming that cpu0 is always populated before cpu1 if(socket_0.max_cpu>1){ socket_num=0; print_i7z_socket_single(socket_0, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_1, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num],old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num],new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num],C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_cpus_observed); }else{ socket_num=1; print_i7z_socket_single(socket_1, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_1, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num],old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num],new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num],C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_cpus_observed); } } } /*int Single_Socket(){ int row, col; // to store the number of rows and // // the number of colums of the screen // // for NCURSES // printf ("i7z DEBUG: In i7z Single_Socket()\n"); sleep (3); //iterator int i; int error_indx; //cpu multiplier int CPU_Multiplier; //current blck value float BLCK; //turbo_mode enabled/disabled flag char TURBO_MODE; int online_cpus[8]; SET_ONLINE_ARRAY_PLUS1(online_cpus) //Use Core-1 as the one to check for the turbo limit //Core number shouldnt matter int CPU_NUM = 0; //bits from 0-63 in this store the various maximum turbo limits int MSR_TURBO_RATIO_LIMIT = 429; // 3B defines till Max 4 Core and the rest bit values from 32:63 were reserved. //Bits:0-7 - core1 int MAX_TURBO_1C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 7, 0, &error_indx); //Bits:15-8 - core2 int MAX_TURBO_2C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 15, 8, &error_indx); //Bits:23-16 - core3 int MAX_TURBO_3C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 23, 16, &error_indx); //Bits:31-24 - core4 int MAX_TURBO_4C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 31, 24, &error_indx); //gulftown/Hexacore support //technically these should be the bits to get for core 5,6 //Bits:39-32 - core4 int MAX_TURBO_5C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 39, 32, &error_indx); //Bits:47-40 - core4 int MAX_TURBO_6C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 47, 40, &error_indx); //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ system ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); system ("grep \"core id\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numPhysical.txt"); system ("grep \"processor\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numLogical.txt"); //At this step, /tmp/numPhysical contains number of physical cores in machine and // /tmp/numPhysical contains number of logical cores in machine //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo FILE *tmp_file; tmp_file = fopen ("/tmp/cpufreq.txt", "r"); char tmp_str[30]; fgets (tmp_str, 30, tmp_file); double cpu_freq_cpuinfo = atof (tmp_str); fclose (tmp_file); //Parse the numPhysical and numLogical file to obtain the number of physical and logical core tmp_file = fopen ("/tmp/numPhysical.txt", "r"); fgets (tmp_str, 30, tmp_file); numPhysicalCores = atoi (tmp_str); fclose (tmp_file); tmp_file = fopen ("/tmp/numLogical.txt", "r"); fgets (tmp_str, 30, tmp_file); numLogicalCores = atoi (tmp_str); fclose (tmp_file); //reading of the number of cores is done fflush (stdout); sleep (1); //Setup stuff for ncurses initscr (); // start the curses mode start_color (); getmaxyx (stdscr, row, col); // get the number of rows and columns refresh (); //Setup for ncurses completed //Print a slew of information on the ncurses window mvprintw (0, 0, "Cpu speed from cpuinfo %0.2fMhz\n", cpu_freq_cpuinfo); mvprintw (1, 0, "cpuinfo might be wrong if cpufreq is enabled. To guess correctly try estimating via tsc\n"); mvprintw (2, 0, "Linux's inbuilt cpu_khz code emulated now\n\n"); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); mvprintw (3, 0, "True Frequency (without accounting Turbo) %0.0f MHz\n", cpu_freq_cpuinfo); //MSR number and hi:low bit of that MSR //This msr contains a lot of stuff, per socket wise //one can pass any core number and then get in multiplier etc int PLATFORM_INFO_MSR = 206; //CE 15:8 int PLATFORM_INFO_MSR_low = 8; int PLATFORM_INFO_MSR_high = 15; //We just need one CPU (we use Core-1) to figure out the multiplier and the bus clock freq. //multiplier doesnt automatically include turbo //note turbo is not guaranteed, only promised //So this msr will only reflect the actual multiplier, rest has to be figured out CPU_NUM = 0; CPU_Multiplier = get_msr_value (CPU_NUM, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //Blck is basically the true speed divided by the multiplier BLCK = cpu_freq_cpuinfo / CPU_Multiplier; mvprintw (4, 0, "CPU Multiplier %dx || Bus clock frequency (BCLK) %0.2f MHz \n", CPU_Multiplier, BLCK); //Get turbo mode status by reading msr within turbo_status TURBO_MODE = turbo_status (); //get_msr_value(CPU_NUM,IA32_MISC_ENABLE, TURBO_FLAG_high,TURBO_FLAG_low); //to find how many cpus are enabled, we could have used sysconf but that will just give the logical numbers //if HT is enabled then the threads of the same core have the same C-state residency number so... //Its imperative to figure out the number of physical and number of logical cores. //sysconf(_SC_NPROCESSORS_ONLN); //number of CPUs is as told via cpuinfo int numCPUs = numPhysicalCores; //Flags and other things about HT. int HT_ON; char HT_ON_str[30]; //HT enabled if num logical > num physical cores if (numLogicalCores > numPhysicalCores) { //printf("Multiplier %d \n", CPU_Multiplier); strncpy (HT_ON_str, "Hyper Threading ON\0", 30); HT_ON = 1; //printf("Multiplier %d \n", CPU_Multiplier); } else { //printf("Multiplier %d \n", CPU_Multiplier); strncpy (HT_ON_str, "Hyper Threading OFF\0", 30); HT_ON = 0; //printf("Multiplier %d \n", CPU_Multiplier); } //printf("Multiplier %d \n", CPU_Multiplier); if (TURBO_MODE == 1) { // && (CPU_Multiplier+1)==MAX_TURBO_2C){ mvprintw (5, 0, "TURBO ENABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier + 1); mvprintw (6, 0, "True Frequency %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier + 1); } else { mvprintw (5, 0, "TURBO DISABLED on %d Cores, %s\n", numPhysicalCores, HT_ON_str); TRUE_CPU_FREQ = BLCK * ((double) CPU_Multiplier); mvprintw (6, 0, "True Frequency %0.2f MHz (%0.2f x [%d]) \n", TRUE_CPU_FREQ, BLCK, CPU_Multiplier); } if (numCPUs >= 2) {mvprintw (7, 0," Max TURBO (if Enabled) with 1/2 Core active %dx / %dx\n", MAX_TURBO_1C, MAX_TURBO_2C);} if (numCPUs >= 4) {mvprintw (8, 0," Max TURBO (if Enabled) with 3/4 Cores active %dx / %dx\n", MAX_TURBO_3C, MAX_TURBO_4C);} if (numCPUs >= 6) {mvprintw (9, 0," Max TURBO (if Enabled) with 5/6 Cores active %dx / %dx\n", MAX_TURBO_5C, MAX_TURBO_6C);} mvprintw (22, 0, "C0 = Processor running without halting"); mvprintw (23, 0, "C1 = Processor running with halts (States >C0 are power saver)"); mvprintw (24, 0, "C3 = Cores running with PLL turned off and core cache turned off"); mvprintw (25, 0, "C6 = Everything in C3 + core state saved to last level cache"); mvprintw (26, 0, " Above values in table are in percentage over the last 1 sec"); mvprintw (27, 0, " Total Logical Cores: [%d], Total Physical Cores: [%d] \n", numLogicalCores, numPhysicalCores); mvprintw (29, 0, " Ctrl+C to exit"); int IA32_PERF_GLOBAL_CTRL = 911; //38F int IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); int IA32_FIXED_CTR_CTL = 909; //38D int IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); //printf("IA32_PERF_GLOBAL_CTRL %d\n",IA32_PERF_GLOBAL_CTRL_Value); //printf("IA32_FIXED_CTR_CTL %d\n",IA32_FIXED_CTR_CTL_Value); unsigned long long int CPU_CLK_UNHALTED_CORE, CPU_CLK_UNHALTED_REF, CPU_CLK_C3, CPU_CLK_C6, CPU_CLK_C1; CPU_CLK_UNHALTED_CORE = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); CPU_CLK_UNHALTED_REF = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); unsigned long long int old_val_CORE[numCPUs], new_val_CORE[numCPUs]; unsigned long long int old_val_REF[numCPUs], new_val_REF[numCPUs]; unsigned long long int old_val_C3[numCPUs], new_val_C3[numCPUs]; unsigned long long int old_val_C6[numCPUs], new_val_C6[numCPUs]; // unsigned long int old_val_C1[numCPUs], new_val_C1[numCPUs]; unsigned long long int old_TSC[numCPUs], new_TSC[numCPUs]; struct timeval tvstart[numCPUs], tvstop[numCPUs]; struct timespec one_second_sleep; one_second_sleep.tv_sec = 0; one_second_sleep.tv_nsec = 999999999; // 1000msec unsigned long int IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); unsigned long int IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[0],-1); mvprintw (11, 0, "Wait...\n"); refresh (); nanosleep (&one_second_sleep, NULL); IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx) - IA32_MPERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx) - IA32_APERF; SET_IF_TRUE(error_indx,online_cpus[0],-1); //printf("Diff. i n APERF = %u, MPERF = %d\n", IA32_MPERF, IA32_APERF); long double C0_time[numCPUs], C1_time[numCPUs], C3_time[numCPUs], C6_time[numCPUs]; double _FREQ[numCPUs], _MULT[numCPUs]; refresh (); mvprintw (11, 0, "Current Freqs\n"); int kk=11, ii; double estimated_mhz; for (;;) { SET_ONLINE_ARRAY_PLUS1(online_cpus) if (kk > 10){ kk=0; for (ii = 0; ii < numCPUs; ii++) { //Set up the performance counters and then start reading from them CPU_NUM = ii; IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); set_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 0x700000003LLU); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); set_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 819); IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); old_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); old_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); old_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); old_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[ii],-1); CONTINUE_IF_TRUE(online_cpus[ii]==-1); old_TSC[ii] = rdtsc (); } } kk++; nanosleep (&one_second_sleep, NULL); mvprintw (13, 0, "\tProcessor :Actual Freq (Mult.) C0%% Halt(C1)%% C3 %% C6 %%\n"); estimated_mhz = estimate_MHz (); for (i = 0; i < numCPUs; i++) { //read from the performance counters //things like halted unhalted core cycles CPU_NUM = i; new_val_CORE[i] = get_msr_value (CPU_NUM, 778, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_REF[i] = get_msr_value (CPU_NUM, 779, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C3[i] = get_msr_value (CPU_NUM, 1020, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_val_C6[i] = get_msr_value (CPU_NUM, 1021, 63, 0, &error_indx); SET_IF_TRUE(error_indx,online_cpus[i],-1); CONTINUE_IF_TRUE(online_cpus[i]==-1); new_TSC[i] = rdtsc (); if (old_val_CORE[i] > new_val_CORE[i]) { //handle overflow CPU_CLK_UNHALTED_CORE = (UINT64_MAX - old_val_CORE[i]) + new_val_CORE[i]; }else{ CPU_CLK_UNHALTED_CORE = new_val_CORE[i] - old_val_CORE[i]; } //number of TSC cycles while its in halted state if ((new_TSC[i] - old_TSC[i]) < CPU_CLK_UNHALTED_CORE) {CPU_CLK_C1 = 0;} else {CPU_CLK_C1 = ((new_TSC[i] - old_TSC[i]) - CPU_CLK_UNHALTED_CORE);} if (old_val_REF[i] > new_val_REF[i]) { //handle overflow CPU_CLK_UNHALTED_REF = (UINT64_MAX - old_val_REF[i]) + new_val_REF[i]; //3.40282366921e38 }else{ CPU_CLK_UNHALTED_REF = new_val_REF[i] - old_val_REF[i]; } if (old_val_C3[i] > new_val_C3[i]) { //handle overflow CPU_CLK_C3 = (UINT64_MAX - old_val_C3[i]) + new_val_C3[i]; }else{ CPU_CLK_C3 = new_val_C3[i] - old_val_C3[i]; } if (old_val_C6[i] > new_val_C6[i]) { //handle overflow CPU_CLK_C6 = (UINT64_MAX - old_val_C6[i]) + new_val_C6[i]; }else{ CPU_CLK_C6 = new_val_C6[i] - old_val_C6[i]; } _FREQ[i] = estimated_mhz * ((long double) CPU_CLK_UNHALTED_CORE / (long double) CPU_CLK_UNHALTED_REF); _MULT[i] = _FREQ[i] / BLCK; C0_time[i] = ((long double) CPU_CLK_UNHALTED_REF / (long double) (new_TSC[i] - old_TSC[i])); C1_time[i] = ((long double) CPU_CLK_C1 / (long double) (new_TSC[i] - old_TSC[i])); C3_time[i] = ((long double) CPU_CLK_C3 / (long double) (new_TSC[i] - old_TSC[i])); C6_time[i] = ((long double) CPU_CLK_C6 / (long double) (new_TSC[i] - old_TSC[i])); if (C0_time[i] < 1e-2) { if (C0_time[i] > 1e-4) {C0_time[i] = 0.01;} else {C0_time[i] = 0;} } if (C1_time[i] < 1e-2) { if (C1_time[i] > 1e-4) {C1_time[i] = 0.01;} else {C1_time[i] = 0;} } if (C3_time[i] < 1e-2) { if (C3_time[i] > 1e-4) {C3_time[i] = 0.01;} else {C3_time[i] = 0;} } if (C6_time[i] < 1e-2) { if (C6_time[i] > 1e-4) {C6_time[i] = 0.01;} else {C6_time[i] = 0;} } //printf("%lld - %lld", CPU_CLK_C6, (new_TSC[i] - old_TSC[i])); } for (i = 0; i < numCPUs; i++){ if(online_cpus[i]==-1){ mvprintw (14 + i, 0, "\tProcessor %d: OFFLINE\n",i + 1); }else{ mvprintw (14 + i, 0, "\tProcessor %d: %0.2f (%.2fx)\t%4.3Lg\t%4.3Lg\t%4.3Lg\t%4.3Lg\n", i + 1, _FREQ[i], _MULT[i], C0_time[i] * 100 , C1_time[i]* 100 - (C3_time[i] + C6_time[i] )* 100, C3_time[i]* 100 , C6_time[i]* 100); //C0_time[i]*100+C1_time[i]*100 around 100 } } TRUE_CPU_FREQ = 0; for (i = 0; i < numCPUs; i++) { if (_FREQ[i] > TRUE_CPU_FREQ) { TRUE_CPU_FREQ = _FREQ[i]; mvprintw (12, 0, "True Frequency %0.2f MHz (Intel specifies largest of below to be running Freq)\n", TRUE_CPU_FREQ); } } refresh (); //shift the new values to the old counter values //so that the next time we use those to find the difference memcpy (old_val_CORE, new_val_CORE, sizeof (unsigned long int) * numCPUs); memcpy (old_val_REF, new_val_REF, sizeof (unsigned long int) * numCPUs); memcpy (old_val_C3, new_val_C3, sizeof (unsigned long int) * numCPUs); memcpy (old_val_C6, new_val_C6, sizeof (unsigned long int) * numCPUs); memcpy (tvstart, tvstop, sizeof (struct timeval) * numCPUs); memcpy (old_TSC, new_TSC, sizeof (unsigned long long int) * numCPUs); } //ENDOF INFINITE FOR LOOP exit (0); return (1); }*/ i7z-0.27.2/i7z_rw_registers.rb0000644000175000017500000003350112023553432014541 0ustar abhiabhi#* ----------------------------------------------------------------------- * # * # * Under GPL v3 # * written by Abhishek Jaiantilal # * much thanks to Antonio Meireles who suggested this idea & helped with testing # * run as sudo ruby i7z_rw_registers.rb # * # * ----------------------------------------------------------------------- */ #!/usr/bin/ruby def print_command_list() print "Do you need help? \n" print "Possible commands are \n" print "help : which will print this list again \n" print "turbo : which examines the turbo status \n" print "multiplier : examines the multipliers \n" print "power : which prints current wattage of the system\n" print "clock : allows for software clock modulation ( a form of throttling )\n" print "system : allows to print some system info\n" print "quit : which will quit the program or just do ctrl + c\n" end IA32_PERF_STATUS = 0x198 #read only IA32_PERF_CTL = 0x199 #read write IA32_MISC_ENABLE = 0x1a0 def num_cores numcores = `cat /proc/cpuinfo | grep 'cpu cores' |head -n 1|sed 's/cpu cores\\s*:\\s//'` return numcores.to_i end def nehalem_or_sandybridge proc_type = `cat /proc/cpuinfo | grep flags |head -n 1| grep avx` if proc_type.chomp.length == 0 return 'Nehalem' else return 'Sandy Bridge' end end def turbo_command_list() print "turbo : which examines the turbo status \n" print " probable commands are\n" print " turbo status : get the current status of turbo\n" print " turbo enable : enable turbo\n" print " turbo disable : disable turbo\n" end def multiplier_command_list() print "multiplier : which allows setting/examining multiplier \n" print " probable commands are\n" print " multiplier set : set the multiplier to given number and ONLY in decimals\n" print " multiplier get : examine the current multiplier\n" end def power_command_list() print "power : which allows setting/examining TDP / TDC\n" print " probable commands are\n" print " power set tdp : set the multiplier to given number and ONLY in decimals\n" print " power set tdc : set the multiplier to given number and ONLY in decimals\n" print " power get : examine the current TDP / TDC\n" end def clock_command_list() print "clock : allows for software clock modulation ( a form of throttling )\n" print " a good link for understanding this is http://paulsiu.wordpress.com/2007/06/23/does-on-demand-clock-modulation-odcm-conserve-battery/\n" print " probable commands are\n" print " clock set : set the number to one of the below or in range between 0-100\n" print " and i will automatically to the value nearest to\n" print " 12.5, 25.0, 37.5, 50.0, 63.5, 75, 87.5 (nehalem)\n" print " sandy bridge supports 6.25% increments\n" print " but, I (the tool) is not smart yet to distinguish between nehalem and sb\n" print " so setting to 12.5 increment\n" print " set to 1 for 12.5%, 2 for 25%, 3 for 37.5%, 4 for 50%, \n" print" 5 for 63.5%, 6 for 75% and 7 for 87.5%\n" print " clock status : get clock modulation status\n" print " clock disable : disable clock modulation\n" end @duty_cycle_array = {0=>"reserved", 1=>'12.5% (default)', 2=>'25%', 3=>'37.5%', 4=>'50%', 5=>'63.5%',6=>'75%',7=>'87.5%'} def get_clock_status() status = `rdmsr 0x19a --bitfield 4:4` print_command('rdmsr 0x19a --bitfield 4:4') if status.to_i == 0 print "Clock modulation is disabled\n" else print "Clock modulation is enabled\n" status = `rdmsr 0x19a --bitfield 3:1` print_command('rdmsr 0x19a --bitfield 3:1') print "Duty Cycle is #{@duty_cycle_array[status.to_i]}\n" end end def set_clock_modulation(mult) if (mult.to_i<0) | (mult.to_i>8) print "Error: clock set , where should be between 1-7\n" print " set to 1 for 12.5%, 2 for 25%, 3 for 37.5%, 4 for 50%, \n" print" 5 for 63.5%, 6 for 75% and 7 for 87.5%\n" return end get_clock_status() mult = mult.to_i << 1 mult = mult | 0x10 for i in (0..12) status = "wrmsr 0x19a -p#{i} #{mult}" print_command(status) system(status) end get_clock_status() end def clock_disable() val = 0x0 for i in (0..(num_cores()*2-1)) status = "wrmsr 0x19a -p#{i} #{val}" print_command(status) system(status) end get_clock_status() end def print_command( str ) print "Running following command in sudo: #{str} \n" end def print_turbo_status() status = `rdmsr 0x1a0 --bitfield 38:38` print_command('rdmsr 0x1a0 --bitfield 38:38') if status.to_i == 1 print "Turbo is Disabled\n" else print "Turbo is Enabled\n" end end def enable_turbo_status() status = `rdmsr 0x1a0 --decimal` print "First checking status\n" print_command('rdmsr 0x1a0 --decimal') status = status.to_i & 0xBFFFFFFFFF #1 the 38th bit command = "wrmsr 0x1a0 #{status}" system(command) print_command(command) status = `rdmsr 0x1a0 --bitfield 38:38` print "Now checking if the update was successful or not\n" print_command('rdmsr 0x1a0 --bitfield 38:38') if status.to_i == 1 print "Turbo is now Disabled, command failed and i dont know whyq\n" else print "Turbo is now Enabled, command succeeded\n" end end def disable_turbo_status() status = `rdmsr 0x1a0 --decimal` status = status.to_i | 0x4000000000 #1 the 38th bit print "First checking status\n" print_command('rdmsr 0x1a0 --decimal') command = "wrmsr 0x1a0 #{status}" system(command) print_command(command) status = `rdmsr 0x1a0 --bitfield 38:38` print "Now checking if the update was successful or not\n" print_command('rdmsr 0x1a0 --bitfield 38:38') if status.to_i == 1 print "Turbo is now Disabled, command succeeded\n" else print "Turbo is now Enabled, command failed and i dont know why\n" end end def get_multiplier() if nehalem_or_sandybridge == 'Nehalem' status = `rdmsr 0x198 --decimal` print_command('rdmsr 0x198 --decimal') status = status.to_i & 0xFFFF else status = `rdmsr 0x198 --decimal --bitfield 15:8` print_command('rdmsr 0x198 --decimal --bitfield 15:8') status = status.to_i & 0xFF end print " Current Multiplier is #{status}\n" status1 = `rdmsr 0xce --decimal --bitfield 47:40` print_command('rdmsr 0xce --decimal --bitfield 47:40') print " Minimum Multiplier possible is #{status1.chomp}\n" status1 = `rdmsr 0xce --decimal --bitfield 15:8` print_command('rdmsr 0xce --decimal --bitfield 15:8') print " Maximum Multiplier in Non-turbo mode is #{status1.chomp}\n" turbo1 = `rdmsr 0x1ad --decimal --bitfield 7:0` print_command('rdmsr 0x1ad --decimal --bitfield 7:0') turbo2 = `rdmsr 0x1ad --decimal --bitfield 15:8` print_command('rdmsr 0x1ad --decimal --bitfield 15:8') turbo3 = `rdmsr 0x1ad --decimal --bitfield 23:16` print_command('rdmsr 0x1ad --decimal --bitfield 23:16') turbo4 = `rdmsr 0x1ad --decimal --bitfield 31:24` print_command('rdmsr 0x1ad --decimal --bitfield 31:24') turbo5 = `rdmsr 0x1ad --decimal --bitfield 39:32` print_command('rdmsr 0x1ad --decimal --bitfield 39:32') turbo6 = `rdmsr 0x1ad --decimal --bitfield 47:40` print_command('rdmsr 0x1ad --decimal --bitfield 47:40') if num_cores()>=5 print " Maximum turbo limit with 1/2/3/4/5/6 cores active is #{turbo1.chomp}/#{turbo2.chomp}/#{turbo3.chomp}/#{turbo4.chomp}/#{turbo5.chomp}/#{turbo6.chomp}\n" elsif (num_cores()<=4 && num_cores()>2) print " Maximum turbo limit with 1/2/3/4 cores active is #{turbo1.chomp}/#{turbo2.chomp}/#{turbo3.chomp}/#{turbo4.chomp}\n" else print " Maximum turbo limit with 1/2 cores active is #{turbo1.chomp}/#{turbo2.chomp}\n" end end def set_multiplier(mult) status1 = `rdmsr 0xce --decimal --bitfield 47:40` minimum_multiplier = status1.chomp.to_i print_command('rdmsr 0xce --decimal --bitfield 47:40') turbo1 = `rdmsr 0x1ad --decimal --bitfield 7:0` maximum_multiplier = turbo1.chomp.to_i print_command('rdmsr 0x1ad --decimal --bitfield 7:0') if (mult < minimum_multiplier) | (mult > maximum_multiplier) print "You asked for a multiplier #{mult}\n" print "The range of input Multiplier is not in range\n" print "Please put it between #{minimum_multiplier} to #{maximum_multiplier}\n" else print "Don't worry if it prints that some wrmsr error message; i dont know the number of cores on your current machine so trying from 0..12" for i in (0..(num_cores()*2-1)) status = "wrmsr 0x199 -p#{i} #{mult}" print_command(status) system(status) end end get_multiplier() #print "Current Multiplier is #{status}\n" end def get_power if nehalem_or_sandybridge != 'Nehalem' print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" else status1 = `rdmsr 0x1ac --bitfield 14:0 --decimal` print_command('rdmsr 0x1ac --bitfield 14:0 --decimal') status2 = `rdmsr 0x1ac --bitfield 30:16 --decimal` print_command('rdmsr 0x1ac --bitfield 30:16 --decimal') print "Current TDP limit is #{status1.to_i * 1/8} watts, TDC limit is #{status2.to_i * 1/8} amps\n" end end def set_tdp(limit) if nehalem_or_sandybridge != 'Nehalem' print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" else status1 = `rdmsr 0x1ac --decimal` print_command('rdmsr 0x1ac --decimal') tdp = (status1.to_i & 0xFFFFFFFFFFFF8000) | (0x8000) | (limit.to_i/0.125) #set bits 14:0, as resolution is 1/8 of a watt/amp status = "wrmsr 0x1ac #{tdp}" print_command(status) system(status) end end def set_tdc(limit) if nehalem_or_sandybridge != 'Nehalem' print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" else status1 = `rdmsr 0x1ac --decimal` print_command('rdmsr 0x1ac --decimal') tdc = (status1.to_i & 0xFFFFFFFF8000FFFF) | (0x80000000) | ((limit.to_i/0.125).to_i << 16) #set bits 30:16, as resolution is 1/8 of a watt/amp status = "wrmsr 0x1ac #{tdc}" print_command(status) system(status) end end #IGNORE THIS FUNCTION - NOT USING IT AT ALL def disable_ida() #status = `rdmsr 0x199` #status = status.to_i(16) #p status #disable_turbo_string = 0x0100 #system("wrmsr 0x199 #{disable_turbo_string}") #read the current opportunistic performance status and then write it. so first STATUS and then CTL curr_status = `rdmsr 0x198 --decimal` print "current performance status 0x#{curr_status}\n" curr_status = (curr_status.to_i | 0x100).to_s(16) print "in order to set ida=disable i will set bit 32 to get the following byte value 0x#{curr_status}\n" curr_command = "wrmsr 0x199 #{curr_status}" print "now executing #{curr_command}\n" system(curr_command) end print "\n\nThis script is totally experimental \n" print "use it in superuser mode to get access to r/w access \n" print "also i need msr-tools installed so that rdmsr and wrmsr can work in sudo\n" print "write quit or ctrl+C to exit\n\n" print "Now for the blurb on why you might find this script useful:\n" print "Throttling cpu on battery is one place, some machines including W520\n" print "have a wierd bios which switches off turbo when machine is booted in\n" print "battery or some bios implement throttling even when the power is within limit\n" print "and this tool should allow you to manually set the multiplier\n" print "Whenever you run a command it will print out what goes in the background\n" print "like what registers were read/written etc, this should allow one to even\n" print "write different scripts to automatically run specifics multiplier in battery\n" print "power and other modes.\n" print "msr-tools are needed. Furthermore \"modprobe msr\" on command line needs to be executed\n" print_command_list() at_exit{print "exiting, thanks for using\n"} while(1) print ">> " $input = STDIN.gets.chomp if $input.downcase.eql? "quit" break; end if $input.length == 0 print_command_list() else commands = $input.split case commands[0].downcase # some commands have 0 level, eg just `help', others have two level 'turbo' and then status, enable and disable. multiplier get has 3 levels multiplier set 12 will set the multplier to 12 when "help" print_command_list() when "turbo" if ! commands[1].nil? case commands[1].downcase when "status" print_turbo_status() when "enable" enable_turbo_status() when "disable" disable_turbo_status() else turbo_command_list() end else turbo_command_list() end when "multiplier" if !commands[1].nil? case commands[1].downcase when "get" get_multiplier() when "set" if !commands[2].nil? set_multiplier(commands[2].to_i) else multiplier_command_list() end else multiplier_command_list() end else multiplier_command_list() end when "power" if !commands[1].nil? case commands[1].downcase when "get" get_power() when "set" if !commands[2].nil? && !commands[3].nil? case commands[2].downcase when "tdp" set_tdp(commands[3]) when "tdc" set_tdc(commands[3]) else power_command_list() end else power_command_list() end else power_command_list() end else power_command_list() end when "clock" if !commands[1].nil? case commands[1].downcase when "status" get_clock_status() when "set" if !commands[2].nil? set_clock_modulation(commands[2]) else clock_command_list() end when "disable" clock_disable() else clock_command_list() end else clock_command_list() end when "system" print "number of cores #{num_cores()}\n" print "trying to distinguish between nehalem/sandy bridge via AVX support... #{nehalem_or_sandybridge}\n" else print_command_list() end end end i7z-0.27.2/Makefile0000644000175000017500000000367712023553432012357 0ustar abhiabhi# # Makefile for i7z, GPL v2, License in COPYING # #makefile updated from patch by anestling #explicitly disable two scheduling flags as they cause segfaults, two more seem to crash the GUI version so putting them #here CFLAGS_FOR_AVOIDING_SEG_FAULT = -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves CFLAGS ?= -O3 CFLAGS += $(CFLAGS_FOR_AVOIDING_SEG_FAULT) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DBUILD_MAIN -Wimplicit-function-declaration LBITS := $(shell getconf LONG_BIT) ifeq ($(LBITS),64) CFLAGS += -Dx64_BIT else CFLAGS += -Dx86 endif CC ?= gcc LIBS += -lncurses -lpthread -lrt -lm INCLUDEFLAGS = BIN = i7z # PERFMON-BIN = perfmon-i7z #future version to include performance monitor, either standalone or integrated SRC = i7z.c helper_functions.c i7z_Single_Socket.c i7z_Dual_Socket.c OBJ = $(SRC:.c=.o) prefix ?= /usr sbindir = $(prefix)/sbin/ docdir = $(prefix)/share/doc/$(BIN)/ mandir ?= $(prefix)/share/man/ all: clean test_exist message: @echo "If the compilation complains about not finding ncurses.h, install ncurses (libncurses5-dev on ubuntu/debian)" bin: message $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $(OBJ) $(LIBS) #http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=644728 for -ltinfo on debian static-bin: message $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $(OBJ) -static-libgcc -DNCURSES_STATIC -static -lpthread -lncurses -lrt -lm -ltinfo # perfmon-bin: message $(OBJ) # $(CC) $(CFLAGS) $(LDFLAGS) -o $(PERFMON-BIN) perfmon-i7z.c helper_functions.c $(LIBS) test_exist: bin @test -f i7z && echo 'Succeeded, now run sudo ./i7z' || echo 'Compilation failed' clean: rm -f *.o $(BIN) distclean: clean rm -f *~ \#* install: $(BIN) install -D -m 0644 doc/i7z.man $(DESTDIR)$(mandir)man1/i7z.1 install -D -m 755 $(BIN) $(DESTDIR)$(sbindir)$(BIN) install -d $(DESTDIR)$(docdir) install -m 0644 README.txt put_cores_offline.sh put_cores_online.sh MAKEDEV-cpuid-msr $(DESTDIR)$(docdir) i7z-0.27.2/cpuinfo.c0000644000175000017500000001622312023553432012515 0ustar abhiabhi#include "stdio.h" #include "string.h" #include "stdlib.h" #include "assert.h" #define MAX_PROCESSORS 32 #define bool int #define false 0 #define true 1 #define MAX_HI_PROCESSORS MAX_PROCESSORS struct cpu_heirarchy_info { int max_online_cpu; int num_sockets; int sibling_num[MAX_HI_PROCESSORS]; int processor_num[MAX_HI_PROCESSORS]; int package_num[MAX_HI_PROCESSORS]; int coreid_num[MAX_HI_PROCESSORS]; int display_cores[MAX_HI_PROCESSORS]; bool HT; }; #define MAX_SK_PROCESSORS (MAX_PROCESSORS/4) struct cpu_socket_info { int max_cpu; int socket_num; int processor_num[MAX_SK_PROCESSORS]; int num_physical_cores; int num_logical_cores; }; int check_and_return_processor(char*strinfo) { char *t1; if (strstr(strinfo,"processor") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } int check_and_return_physical_id(char*strinfo) { char *t1; if (strstr(strinfo,"physical id") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } int check_and_return_core_id(char*strinfo) { char *t1; if (strstr(strinfo,"core id") !=NULL) { strtok(strinfo,":"); t1 = strtok(NULL, " "); return(atoi(t1)); } else { return(-1); } } void construct_sibling_list(struct cpu_heirarchy_info* chi) { int i,j,core_id,socket_id; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); chi->sibling_num[i]=-1; } chi->HT=false; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); core_id = chi->coreid_num[i]; socket_id = chi->package_num[i]; for (j=i+1;j< chi->max_online_cpu ;j++) { assert(j < MAX_HI_PROCESSORS); if (chi->coreid_num[j] == core_id && chi->package_num[j] == socket_id) { chi->sibling_num[j] = i; chi->sibling_num[i] = j; chi->display_cores[i] = 1; chi->display_cores[j] = -1; chi->HT=true; continue; } } } //for cores that donot have a sibling put in 1 for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); if (chi->sibling_num[i] ==-1) chi->display_cores[i] = 1; } } void construct_socket_information(struct cpu_heirarchy_info* chi,struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1) { int i; char socket_1_list[200]="", socket_0_list[200]=""; for (i=0;i< chi->max_online_cpu ;i++) { assert(i < MAX_HI_PROCESSORS); if (chi->display_cores[i]!=-1) { if (chi->package_num[i]==0) { assert(socket_0->max_cpu < MAX_SK_PROCESSORS); socket_0->processor_num[socket_0->max_cpu]=chi->processor_num[i]; socket_0->max_cpu++; socket_0->num_physical_cores++; socket_0->num_logical_cores++; } if (chi->package_num[i]==1) { assert(socket_1->max_cpu < MAX_SK_PROCESSORS); socket_1->processor_num[socket_1->max_cpu]=chi->processor_num[i]; socket_1->max_cpu++; socket_1->num_physical_cores++; socket_1->num_logical_cores++; } } else { if (chi->package_num[i]==0) { socket_0->num_logical_cores++; } if (chi->package_num[i]==1) { socket_1->num_logical_cores++; } } } } void print_socket_information(struct cpu_socket_info* socket) { int i; char socket_list[200]=""; for (i=0;i< socket->max_cpu ;i++) { assert(i < MAX_SK_PROCESSORS); if (socket->processor_num[i]!=-1) { sprintf(socket_list,"%s%d,",socket_list,socket->processor_num[i]); } } printf("Socket-%d [num of cpus %d physical %d logical %d] %s\n",socket->socket_num,socket->max_cpu,socket->num_physical_cores,socket->num_logical_cores,socket_list); } void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi) { int i; FILE *fp = fopen("/proc/cpuinfo","r"); char strinfo[200]; int processor_num, physicalid_num, coreid_num; int it_processor_num=-1, it_physicalid_num=-1, it_coreid_num=-1; int tmp_processor_num, tmp_physicalid_num, tmp_coreid_num; int old_processor_num=-1; if (fp!=NULL) { while ( fgets(strinfo,200,fp) != NULL) { printf(strinfo); tmp_processor_num = check_and_return_processor(strinfo); tmp_physicalid_num = check_and_return_physical_id(strinfo); tmp_coreid_num = check_and_return_core_id(strinfo); if (tmp_processor_num != -1) { it_processor_num++; processor_num = tmp_processor_num; assert(it_processor_num < MAX_HI_PROCESSORS); chi->processor_num[it_processor_num] = processor_num; } if (tmp_physicalid_num != -1) { it_physicalid_num++; physicalid_num = tmp_physicalid_num; assert(it_physicalid_num < MAX_HI_PROCESSORS); chi->package_num[it_physicalid_num] = physicalid_num; } if (tmp_coreid_num != -1) { it_coreid_num++; coreid_num = tmp_coreid_num; assert(it_coreid_num < MAX_HI_PROCESSORS); chi->coreid_num[it_coreid_num] = coreid_num; } if (processor_num != old_processor_num) { old_processor_num = processor_num; } } } chi->max_online_cpu = it_processor_num+1; } void print_CPU_Heirarchy(struct cpu_heirarchy_info chi) { int i; printf("Legend: processor number is the processor number as linux knows, socket number is the socket number,\n \ coreid number is the core with which this processor is associated, thus for HT machines there will be 2 processors\n\ sharing the same core id. display core is to specify if i need to show the information about this core or not (i.e.\n\ if i am already showing information about a core then i dont need to show information about the sibling\n"); for (i=0;i < chi.max_online_cpu;i++) { assert(i < MAX_HI_PROCESSORS); printf("--[%d] Processor number %d\n",i,chi.processor_num[i]); printf("--[%d] Socket number/Sibling number %d,%d\n",i,chi.package_num[i],chi.sibling_num[i]); printf("--[%d] Core id number %d\n",i,chi.coreid_num[i]); printf("--[%d] Display core %d\n\n",i,chi.display_cores[i]); } } int main() { struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1); print_socket_information(&socket_0); print_socket_information(&socket_1); } i7z-0.27.2/README.txt0000644000175000017500000000664412023752273012416 0ustar abhiabhilicense: My code is GPLv2, Details in COPYING Current Version: svn-103 (Sep/2012) Compiling: 32/64-bit linux: make Running: sudo ./i7z needs sudo as MSR are usually only superuser readable/writeable. or if the device nodes are readable under your account then they will work out fine without the sudo need ncurses library: usually something like libncurses on debian. also needs support of MSR (model specific register) in kernel. Usually most kernels have it. Else run the MAKEDEV file. I do modprobing of msr within the C-program. I added in new code that shows a nice GUI. The Makefile for that is in GUI/ subdirectory. Just install a couple of qt packages and you should be all set to run it. There is a README file that lists those packages. Run the following commands in GUI directory: qmake; make clean; make Running GUI: sudo ./i7z_GUI Installation sudo make install Version and Bug History: v svn 103 (Sep/2012) some fixes for segv fault when cpuid code is not inline v svn-43 (27/May/2010) moved some global variables into individual functions. removed a redundant line that was bieng printed GUI version should support upto 12 physical cores. can be easily edited for more cores. v svn-40 (27/May/2010) fixed bugs in dual and single socket when there are too many cores. v svn-36 (18/May/2010) Fixed a bug with printing the Multiplier Line when only 1 core was enabled. v svn-31 (17/May/2010) Supports Dual sockets. Allows for on the fly disabling/enabling of cores without crashing. v0.21-4 (22/Feb/2010) No bugs fixed, except better documentation of the code and fixing on the Makefiles, c/header files and better loading/checking of msr v0.21-3 (13/Feb/2010) Minor Bug Fix, that happened as auto typecasting of double to float wasn't done A variable (numLogical) was getting overwritten, so moved it to global Seems that flags for optimization were screwing things up, so now no optimization GUI still has -O1 optimization flags BTW why sudden increase from 0.2-1 to 0.21-3. There were 3 minor edits in between And then for me 0.21 and 0.2 are just 0.01 apart rather then 19 minor aparts. I realised it too late and the svn was updated so many times that i'll keep it this way this time v0.21 (12/Feb/2010) Lots of edits. Namely changed the way the number of cores were always fixed at 4 Now arbitrary number of cores can be detected, thus i3, i5, i7 and gulftown (6-cores) can be detected. Also added code to detect the whole nehalem family rather than just i7 Removed Intel_CPUID directory which was used earlier to know the number of logical and physical processor. It was iffy when cores where shut down in OS and when license was concerned. Now i use just /proc/cpuinfo to figure out stuff. v0.2 added a gui version that uses qt4. makefile in GUI subdirectory now C0+C1+C3+C6 = 100% v0.1 simple i7 detection utility for overclockers and clockers :) v0.01- very simple program to examine i7 feature clocking and running with speedstep Checked on 64-bit linux only. Should work on 32-bit too. need ncurses library: usually something like libncurses on debian. also needs support of MSR (model specific register) in kernel. Usually most kernels have it. Else run the MAKEDEV file. I do modprobing of msr within the C-program. coder: Abhishek Jaiantilal (abhishek.jaiantilal@colorado.edu) i7z-0.27.2/doc/0000755000175000017500000000000012023752313011446 5ustar abhiabhii7z-0.27.2/doc/i7z.man0000644000175000017500000000347312023553432012664 0ustar abhiabhi.TH i7z 1 "20 July 2012" .SH NAME i7z \- A better i7 (and now i3, i5) reporting tool for Linux. .SH SYNOPSIS \fBi7z [OPTION]\fP, [OPTION] is optional. i7z needs to be run in super user (root) mode. .SH DESCRIPTION i7z runs the i7z, ncurses based, program without any options. i7z will print out the C-states and temperature for i3, i5 and i7 based Core processors from Intel (including Nehalems, Sandy Bridge and Ivy Bridge). .SH OPTIONS .TP \fB-h, --help \fPshow the list of options available with the i7z tool. .TP \fB-w [a|l], --write [a,l] \fPLogging of the frequencies can be turned on with this options. Option "-w a" or "--write a" will append to the log file. Option "-w l" or "--write l" will replace the log file. .TP \fB-l, --logfile [FILENAME] \fPChange the log file name to the specified FILENAME. Default logging file is cpu_freq_log.txt (single socket) or cpu_freq_log_dual%d.txt (dual socket, %d is either 0, 1). .TP \fB--socket0 [SOCKETNUM], --socket1 [SOCKETNUM] \fPThe tool can print information for about 2 sockets at once at the most. The top view will be, by default, of the first socket (controlled by --socket0) and the bottom view will be of the second socket (controlled by --socket1). Supply the appropriate value of 0 or 1 or more for SOCKETNUM (if there are more sockets on the machine) to show in the top and bottom view. .TP \fB--nogui \fPDisable the GUI. Useful when the only need is logging. .SH Example To print for two sockets and also change the log file (log to /tmp/logfilei7z) i7z \-\-socket0 0 \-\-socket1 1 \-logfile /tmp/logfilei7z \-w l .SH BUGS Do report bugs or feature enhancement as an issue at http://code.google.com/p/i7z. .SH AUTHORS Written in 2010, by Abhishek Jaiantilal (abhirana @ gmail.com). i7z is licensed under the terms of the GNU General Public License (GPL) version 2.