├── .gitignore ├── src ├── GUI │ ├── compile_me.sh │ ├── README_GUI.txt │ ├── i7z_GUI.pro │ ├── i7z_GUI.moc │ ├── Makefile │ └── i7z_GUI.cpp ├── intel.h ├── intel.c ├── perfmon-i7z │ ├── README.txt │ ├── Makefile │ ├── perfmon-i7z.h │ ├── perfmon-i7z.cpp │ └── helper_functions.cpp ├── i7z.h ├── i7z.c ├── log.c └── helper_functions.c ├── scripts ├── MAKEDEV-cpuid-msr ├── test_cpuid_issue.cpp ├── cpuinfo.c └── i7z_rw_registers.rb ├── Makefile ├── doc └── i7z.man ├── README └── COPYING /.gitignore: -------------------------------------------------------------------------------- 1 | GUI/i7z_GUI 2 | i7z -------------------------------------------------------------------------------- /src/GUI/compile_me.sh: -------------------------------------------------------------------------------- 1 | #make clean 2 | #rm Makefile 3 | #qmake-qt4 -project 4 | #qmake-qt4 5 | qmake 6 | make clean 7 | make 8 | -------------------------------------------------------------------------------- /src/intel.h: -------------------------------------------------------------------------------- 1 | enum intel_procs { 2 | INTEL_NEHALEM, 3 | INTEL_WESTMERE, 4 | INTEL_SANDYBRIDGE, 5 | INTEL_IVYBRIDGE, 6 | INTEL_HASWELL, 7 | INTEL_BROADWELL, 8 | INTEL_SKYLAKE, 9 | INTEL_KABYLAKE, 10 | INTEL_CANNONLAKE 11 | }; 12 | -------------------------------------------------------------------------------- /scripts/MAKEDEV-cpuid-msr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #this script is sourced from msr-tools package 4 | 5 | msr_major=202 6 | cpuid_major=203 7 | n=0 8 | while [ $n -lt 32 ]; do 9 | mkdir -m 0755 -p /dev/cpu/$n 10 | mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n 11 | mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n 12 | n=`expr $n + 1` 13 | done 14 | 15 | -------------------------------------------------------------------------------- /src/GUI/README_GUI.txt: -------------------------------------------------------------------------------- 1 | By Abhishek Jaiantilal 2 | Under GPL v2 3 | 4 | 5 | 6 | #to make the gui working you will need qt4 installed. 7 | libqt4-dev, qmake-qt4 should be enough i think 8 | 9 | running the Makefile should be enough 10 | 11 | svn-r43 12 | Wworks for Dual Socket Boards but wont work if core is taken offline while the tool is running. 13 | 14 | Right way of compiling is the following 3 steps 15 | 16 | qmake 17 | make clean 18 | make -------------------------------------------------------------------------------- /src/GUI/i7z_GUI.pro: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # Automatically generated by qmake (2.01a) Tue Jan 26 22:31:53 2010 3 | ###################################################################### 4 | 5 | TEMPLATE = app 6 | TARGET = 7 | DEPENDPATH += . 8 | INCLUDEPATH += . 9 | CONFIG += debug 10 | CFLAGS += #QMAKE_*FLAGS are where the gcc flags should be passed 11 | CXXFLAGS += 12 | # Input 13 | SOURCES += i7z_GUI.cpp ../log.c 14 | LIBS += -lncurses 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for i7z, GPL v2, License in COPYING 2 | 3 | CFLAGS ?= -O3 -Wall -Wextra 4 | CFLAGS += -D_GNU_SOURCE 5 | LIBS += -lncurses -lpthread -lrt -lm 6 | INCLUDEFLAGS = 7 | CC ?= gcc 8 | 9 | BIN = i7z 10 | SRC = $(wildcard src/*.c) 11 | OBJ = $(SRC:.c=.o) 12 | 13 | prefix ?= /usr/local 14 | sbindir = $(prefix)/sbin/ 15 | docdir = $(prefix)/share/doc/$(BIN)/ 16 | mandir ?= $(prefix)/share/man/ 17 | 18 | bin: $(OBJ) 19 | $(CC) $(CFLAGS) -o $(BIN) $(OBJ) $(LIBS) 20 | 21 | # perfmon-bin: message $(OBJ) 22 | # $(CC) $(CFLAGS) -o $(PERFMON-BIN) perfmon-i7z.c helper_functions.c $(LIBS) 23 | 24 | clean: 25 | rm -f src/*.o $(BIN) 26 | 27 | distclean: clean 28 | rm -f *~ \#* 29 | 30 | install: $(BIN) 31 | install -D -m 0644 doc/i7z.man $(DESTDIR)$(mandir)man1/i7z.1 32 | install -D -m 755 $(BIN) $(DESTDIR)$(sbindir)$(BIN) 33 | -------------------------------------------------------------------------------- /src/intel.c: -------------------------------------------------------------------------------- 1 | #include "intel.h" 2 | 3 | int get_intel_model (int modelnumber) { 4 | switch (modelnumber) { 5 | case 0x1E: 6 | case 0x1F: 7 | case 0x1A: 8 | case 0x2E: 9 | return INTEL_NEHALEM; 10 | case 0x25: 11 | case 0x2C: 12 | case 0x2F: 13 | return INTEL_WESTMERE; 14 | case 0x2A: 15 | case 0x2D: 16 | return INTEL_SANDYBRIDGE; 17 | case 0x3A: 18 | case 0x3E: 19 | return INTEL_IVYBRIDGE; 20 | case 0x3C: 21 | case 0x3F: 22 | case 0x45: 23 | case 0x46: 24 | return INTEL_HASWELL; 25 | case 0x3D: 26 | case 0x47: 27 | case 0x4F: 28 | case 0x56: 29 | return INTEL_BROADWELL; 30 | case 0x4E: 31 | case 0x5E: 32 | case 0x55: 33 | return INTEL_SKYLAKE; 34 | case 0x8E: 35 | case 0x9E: 36 | return INTEL_KABYLAKE; 37 | case 0x66: 38 | return INTEL_CANNONLAKE; 39 | } 40 | return -1; 41 | } 42 | -------------------------------------------------------------------------------- /src/perfmon-i7z/README.txt: -------------------------------------------------------------------------------- 1 | By Abhishek Jaiantilal (abhishek.jaiantilal @@ colorado.edu) 2 | 3 | how to run? 4 | 1. make 5 | 2. sudo ./perfmon-i7z 6 | 7 | what does it do? 8 | this is a pre-alpha program to know what your machine is doing at your behest 9 | or behind your back. 10 | 11 | it uses performance monitoring counters to understand what type of cycles are 12 | being run in the background, like int, floats or memory cycles. 13 | 14 | a hypothesis is that the number of cycles executed cause a proportional increase 15 | in power consumption (depending on how much area does that unit occupies on the 16 | chip die) 17 | 18 | limitations (i can recall) 19 | 1. right now it runs on the first 4 cores, with a bit of coding it should be 20 | extendable to more cores/packages 21 | 2. works on a couple of my machine (4 core nehalem, 6 core SB) and mysteriously 22 | doesn't work on a 4 core SB machine. i have to look into that 23 | 3. should be straightforward to extend on older machines like core2 which have a 24 | slightly less number of PMC counters 25 | 4. i lost a backup in which i estimated cpu_frequency on the fly, this version has 26 | it hardcoded, i dont know if that shows wrong values. i will have to look into that. 27 | 28 | so why did this program come into being? 29 | 1. to prove that power and cycles executed have a direct relationship. ask anyone 30 | who has run avx-linx on their SB machine, or linx on their machine! 31 | 2. i had trouble getting vtune/perfmon and other fancy tools to take least amount of 32 | cpu usage while giving me the right values for the various counters. -------------------------------------------------------------------------------- /src/perfmon-i7z/Makefile: -------------------------------------------------------------------------------- 1 | #ident "$Id: Makefile,v 1.2 2004/07/20 15:54:59 hpa Exp $" 2 | ## ----------------------------------------------------------------------- 3 | ## 4 | ## Copyright 2000 Transmeta Corporation - All Rights Reserved 5 | ## 6 | ## This program is free software; you can redistribute it and/or modify 7 | ## it under the terms of the GNU General Public License as published by 8 | ## the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, 9 | ## USA; either version 2 of the License, or (at your option) any later 10 | ## version; incorporated herein by reference. 11 | ## 12 | ## ----------------------------------------------------------------------- 13 | 14 | # 15 | # Makefile for MSRs 16 | # 17 | 18 | #makefile updated from patch by anestling 19 | 20 | CFLAGSANY = -g -O0 -fomit-frame-pointer -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DBUILD_MAIN -Wall 21 | 22 | LBITS := $(shell getconf LONG_BIT) 23 | ifeq ($(LBITS),64) 24 | CFLAGS = $(CFLAGSANY) -Dx64_BIT 25 | else 26 | CFLAGS = $(CFLAGSANY) -Dx86 27 | endif 28 | 29 | CC = g++ 30 | 31 | LDFLAGS = -lncurses -lpthread 32 | INCLUDEFLAGS = 33 | 34 | OBJS = helper_functions 35 | 36 | BIN = perfmon-i7z 37 | SRC = perfmon-i7z.cpp helper_functions.cpp 38 | 39 | sbindir = /usr/sbin 40 | 41 | all: bin 42 | 43 | bin: 44 | $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDEFLAGS) $(SRC) -o $(BIN) 45 | 46 | debug: 47 | $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDEFLAGS) $(SRC) -o $(BIN) -g 48 | 49 | clean: 50 | rm -f *.o *~ $(BIN) 51 | 52 | distclean: clean 53 | rm -f *~ \#* 54 | 55 | install: all 56 | install -m 755 $(BIN) $(sbindir) 57 | 58 | -------------------------------------------------------------------------------- /doc/i7z.man: -------------------------------------------------------------------------------- 1 | .TH i7z 1 "20 July 2012" 2 | .SH NAME 3 | i7z \- A better i7 (and now i3, i5) reporting tool for Linux. 4 | .SH SYNOPSIS 5 | \fBi7z [OPTION]\fP, [OPTION] is optional. i7z needs to be run in super user (root) mode. 6 | .SH DESCRIPTION 7 | 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). 8 | .SH OPTIONS 9 | .TP 10 | \fB-h, --help \fPshow the list of options available with the i7z tool. 11 | .TP 12 | \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. 13 | .TP 14 | \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). 15 | .TP 16 | \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. 17 | .TP 18 | \fB--nogui \fPDisable the GUI. Useful when the only need is logging. 19 | .SH Example 20 | To print for two sockets and also change the log file (log to /tmp/logfilei7z) 21 | 22 | i7z \-\-socket0 0 \-\-socket1 1 \-logfile /tmp/logfilei7z \-w l 23 | 24 | .SH BUGS 25 | Do report bugs or feature enhancement as an issue at http://code.google.com/p/i7z. 26 | 27 | .SH AUTHORS 28 | Written in 2010, by Abhishek Jaiantilal (abhirana @ gmail.com). i7z is licensed under the terms of the GNU General Public License (GPL) version 2. 29 | -------------------------------------------------------------------------------- /scripts/test_cpuid_issue.cpp: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "memory.h" 3 | 4 | static inline void cpuid (unsigned int info, unsigned int *eax, unsigned int *ebx, 5 | unsigned int *ecx, unsigned int *edx) 6 | { 7 | unsigned int _eax = info, _ebx, _ecx, _edx; 8 | asm volatile ("mov %%ebx, %%edi;" // save ebx (for PIC) 9 | "cpuid;" 10 | "mov %%ebx, %%esi;" // pass to caller 11 | "mov %%edi, %%ebx;" // restore ebx 12 | :"+a" (_eax), "=S" (_ebx), "=c" (_ecx), "=d" (_edx) 13 | : /* inputs: eax is handled above */ 14 | :"edi" /* clobbers: we hit edi directly */); 15 | if (eax) *eax = _eax; 16 | if (ebx) *ebx = _ebx; 17 | if (ecx) *ecx = _ecx; 18 | if (edx) *edx = _edx; 19 | } 20 | 21 | void get_familyinformation () 22 | { 23 | unsigned int a, b, c, d; 24 | // earlier i thought that NULL was the issue but 25 | cpuid (1, &b, NULL, NULL, NULL); 26 | //cpuid (1, &b, &a, &c, &d); 27 | // printf ("eax %x\n", b); 28 | /* 29 | proc_info->stepping = b & 0x0000000F; //bits 3:0 30 | proc_info->model = (b & 0x000000F0) >> 4; //bits 7:4 31 | proc_info->family = (b & 0x00000F00) >> 8; //bits 11:8 32 | proc_info->processor_type = (b & 0x00007000) >> 12; //bits 13:12 33 | proc_info->extended_model = (b & 0x000F0000) >> 16; //bits 19:16 34 | proc_info->extended_family = (b & 0x0FF00000) >> 20; //bits 27:20 35 | */ 36 | } 37 | void get_vendor (char *vendor_string) 38 | { 39 | //get vendor name 40 | unsigned int a, b, c, d; 41 | cpuid (0, &a, &b, &c, &d); 42 | memcpy (vendor_string, &b, 4); 43 | memcpy (&vendor_string[4], &d, 4); 44 | memcpy (&vendor_string[8], &c, 4); 45 | vendor_string[12] = '\0'; 46 | // printf("Vendor %s\n",vendor_string); 47 | } 48 | 49 | int main() 50 | { 51 | printf("i will print success on quitting\n"); 52 | fflush(stdout); 53 | 54 | char vendor_string[13]; 55 | get_vendor(vendor_string); 56 | 57 | if ((strcmp (vendor_string, "GenuineIntel") == 0)) { 58 | printf ("i7z DEBUG: Found Intel Processor\n"); 59 | } else { 60 | printf 61 | ("this was designed to be a intel proc utility. You can perhaps mod it for your machine?\n"); 62 | } 63 | 64 | get_familyinformation(); 65 | 66 | printf("working\n"); 67 | fflush(stdout); 68 | } 69 | -------------------------------------------------------------------------------- /src/GUI/i7z_GUI.moc: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Meta object code from reading C++ file 'i7z_GUI.cpp' 3 | ** 4 | ** Created: Fri Sep 13 10:43:03 2013 5 | ** by: The Qt Meta Object Compiler version 63 (Qt 4.8.4) 6 | ** 7 | ** WARNING! All changes made in this file will be lost! 8 | *****************************************************************************/ 9 | 10 | #if !defined(Q_MOC_OUTPUT_REVISION) 11 | #error "The header file 'i7z_GUI.cpp' doesn't include ." 12 | #elif Q_MOC_OUTPUT_REVISION != 63 13 | #error "This file was generated using the moc from 4.8.4. It" 14 | #error "cannot be used with the include files from this version of Qt." 15 | #error "(The moc has changed too much.)" 16 | #endif 17 | 18 | QT_BEGIN_MOC_NAMESPACE 19 | static const uint qt_meta_data_MyWidget[] = { 20 | 21 | // content: 22 | 6, // revision 23 | 0, // classname 24 | 0, 0, // classinfo 25 | 1, 14, // methods 26 | 0, 0, // properties 27 | 0, 0, // enums/sets 28 | 0, 0, // constructors 29 | 0, // flags 30 | 0, // signalCount 31 | 32 | // slots: signature, parameters, type, tag, flags 33 | 10, 9, 9, 9, 0x08, 34 | 35 | 0 // eod 36 | }; 37 | 38 | static const char qt_meta_stringdata_MyWidget[] = { 39 | "MyWidget\0\0UpdateWidget()\0" 40 | }; 41 | 42 | void MyWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) 43 | { 44 | if (_c == QMetaObject::InvokeMetaMethod) { 45 | Q_ASSERT(staticMetaObject.cast(_o)); 46 | MyWidget *_t = static_cast(_o); 47 | switch (_id) { 48 | case 0: _t->UpdateWidget(); break; 49 | default: ; 50 | } 51 | } 52 | Q_UNUSED(_a); 53 | } 54 | 55 | const QMetaObjectExtraData MyWidget::staticMetaObjectExtraData = { 56 | 0, qt_static_metacall 57 | }; 58 | 59 | const QMetaObject MyWidget::staticMetaObject = { 60 | { &QWidget::staticMetaObject, qt_meta_stringdata_MyWidget, 61 | qt_meta_data_MyWidget, &staticMetaObjectExtraData } 62 | }; 63 | 64 | #ifdef Q_NO_DATA_RELOCATION 65 | const QMetaObject &MyWidget::getStaticMetaObject() { return staticMetaObject; } 66 | #endif //Q_NO_DATA_RELOCATION 67 | 68 | const QMetaObject *MyWidget::metaObject() const 69 | { 70 | return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; 71 | } 72 | 73 | void *MyWidget::qt_metacast(const char *_clname) 74 | { 75 | if (!_clname) return 0; 76 | if (!strcmp(_clname, qt_meta_stringdata_MyWidget)) 77 | return static_cast(const_cast< MyWidget*>(this)); 78 | return QWidget::qt_metacast(_clname); 79 | } 80 | 81 | int MyWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a) 82 | { 83 | _id = QWidget::qt_metacall(_c, _id, _a); 84 | if (_id < 0) 85 | return _id; 86 | if (_c == QMetaObject::InvokeMetaMethod) { 87 | if (_id < 1) 88 | qt_static_metacall(this, _c, _id, _a); 89 | _id -= 1; 90 | } 91 | return _id; 92 | } 93 | QT_END_MOC_NAMESPACE 94 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | license: My code is GPLv2, Details in COPYING 2 | Current Version: git-93 (May/2013) 3 | 4 | Prerequisites: 5 | Ivy Bridge processors seem to need phc_intel to function correctly. 6 | 7 | Compiling: 8 | 32/64-bit linux: 9 | make 10 | 11 | Running: 12 | sudo ./i7z 13 | 14 | needs sudo as MSR are usually only superuser readable/writeable. or if the device nodes 15 | are readable under your account then they will work out fine without the sudo 16 | 17 | need ncurses library: usually something like libncurses on debian. 18 | also needs support of MSR (model specific register) in kernel. Usually most kernels 19 | have it. Else run the MAKEDEV file. I do modprobing of msr within the C-program. 20 | 21 | 22 | I added in new code that shows a nice GUI. 23 | The Makefile for that is in GUI/ subdirectory. Just install a couple of qt packages 24 | and you should be all set to run it. There is a README file that lists those packages. 25 | Run the following commands in GUI directory: qmake; make clean; make 26 | 27 | Running GUI: 28 | sudo ./i7z_GUI 29 | 30 | 31 | Installation 32 | sudo make install 33 | 34 | 35 | Version and Bug History: 36 | v git-93 (27/May/2013) 37 | added full (lol) support for Ivy Bridge 38 | 39 | v svn 103 (Sep/2012) 40 | some fixes for segv fault when cpuid code is not inline 41 | 42 | v svn-43 (27/May/2010) 43 | moved some global variables into individual functions. 44 | removed a redundant line that was bieng printed 45 | GUI version should support upto 12 physical cores. can be easily edited for more cores. 46 | 47 | v svn-40 (27/May/2010) 48 | fixed bugs in dual and single socket when there are too many cores. 49 | 50 | v svn-36 (18/May/2010) 51 | Fixed a bug with printing the Multiplier Line when only 1 core was enabled. 52 | 53 | v svn-31 (17/May/2010) 54 | Supports Dual sockets. Allows for on the fly disabling/enabling of cores without 55 | crashing. 56 | 57 | v0.21-4 (22/Feb/2010) 58 | No bugs fixed, except better documentation of the code and fixing on the Makefiles, 59 | c/header files and better loading/checking of msr 60 | 61 | v0.21-3 (13/Feb/2010) 62 | Minor Bug Fix, that happened as auto typecasting of double to float wasn't done 63 | A variable (numLogical) was getting overwritten, so moved it to global 64 | Seems that flags for optimization were screwing things up, so now no optimization 65 | GUI still has -O1 optimization flags 66 | 67 | BTW why sudden increase from 0.2-1 to 0.21-3. There were 3 minor edits in between 68 | And then for me 0.21 and 0.2 are just 0.01 apart rather then 19 minor aparts. 69 | I realised it too late and the svn was updated so many times that i'll keep it 70 | this way this time 71 | 72 | v0.21 (12/Feb/2010) 73 | Lots of edits. Namely changed the way the number of cores were always fixed at 4 74 | Now arbitrary number of cores can be detected, thus i3, i5, i7 and gulftown (6-cores) 75 | can be detected. Also added code to detect the whole nehalem family rather than just i7 76 | 77 | Removed Intel_CPUID directory which was used earlier to know the number of logical 78 | and physical processor. It was iffy when cores where shut down in OS and when license 79 | was concerned. Now i use just /proc/cpuinfo to figure out stuff. 80 | 81 | v0.2 82 | 83 | added a gui version that uses qt4. makefile in GUI subdirectory 84 | now C0+C1+C3+C6 = 100% 85 | 86 | v0.1 87 | 88 | simple i7 detection utility for overclockers and clockers :) 89 | 90 | v0.01- very simple program to examine i7 feature clocking and running with speedstep 91 | Checked on 64-bit linux only. Should work on 32-bit too. 92 | 93 | need ncurses library: usually something like libncurses on debian. 94 | also needs support of MSR (model specific register) in kernel. Usually most kernels 95 | have it. Else run the MAKEDEV file. I do modprobing of msr within the C-program. 96 | 97 | 98 | 99 | 100 | 101 | coder: Abhishek Jaiantilal (abhishek.jaiantilal@colorado.edu). And suggestions/help from multiple people, let me know if i am missing your contribution. 102 | contributor: raininja 103 | contributor: Richard Hull 104 | contributor: andareed -------------------------------------------------------------------------------- /src/perfmon-i7z/perfmon-i7z.h: -------------------------------------------------------------------------------- 1 | //i7z.h 2 | /* ----------------------------------------------------------------------- * 3 | * 4 | * Copyright 2009 Abhishek Jaiantilal 5 | * 6 | * Under GPL v2 7 | * 8 | * ----------------------------------------------------------------------- */ 9 | 10 | #define i7z_VERSION_INFO "svn-r43-(31-may-2010)" 11 | 12 | #define CPU_FREQUENCY_LOGGING_FILE "cpu_freq_log.txt" 13 | 14 | //structure to store the information about the processor 15 | #define proccpuinfo "/proc/cpuinfo" 16 | 17 | #ifndef bool 18 | #define bool int 19 | #endif 20 | #define false 0 21 | #define true 1 22 | 23 | #define MAX_PROCESSORS 32 24 | #define MAX_HI_PROCESSORS MAX_PROCESSORS 25 | #define MAX_SK_PROCESSORS (MAX_PROCESSORS/4) 26 | 27 | struct program_options{ 28 | int logging; //0=no logging, 1=logging, 2=appending 29 | }; 30 | 31 | struct cpu_heirarchy_info { 32 | int max_online_cpu; 33 | int num_sockets; 34 | int sibling_num[MAX_HI_PROCESSORS]; 35 | int processor_num[MAX_HI_PROCESSORS]; 36 | int package_num[MAX_HI_PROCESSORS]; 37 | int coreid_num[MAX_HI_PROCESSORS]; 38 | int display_cores[MAX_HI_PROCESSORS]; 39 | bool HT; 40 | }; 41 | 42 | struct cpu_socket_info { 43 | int max_cpu; 44 | int socket_num; 45 | int processor_num[MAX_SK_PROCESSORS]; 46 | int num_physical_cores; 47 | int num_logical_cores; 48 | }; 49 | 50 | struct family_info 51 | { 52 | char stepping; 53 | char model; 54 | char family; 55 | char processor_type; 56 | char extended_model; 57 | int extended_family; 58 | }; 59 | 60 | //read TSC() code for 32 and 64-bit 61 | //http://www.mcs.anl.gov/~kazutomo/rdtsc.html 62 | 63 | #ifndef x64_BIT 64 | //code for 32 bit 65 | static __inline__ unsigned long long int 66 | rdtsc () 67 | { 68 | unsigned long long int x; 69 | __asm__ volatile (".byte 0x0f, 0x31":"=A" (x)); 70 | return x; 71 | } 72 | #endif 73 | 74 | #ifdef x64_BIT 75 | //code for 32 bit 76 | static __inline__ unsigned long long 77 | rdtsc (void) 78 | { 79 | unsigned hi, lo; 80 | __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); 81 | return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); 82 | } 83 | #endif 84 | 85 | 86 | void print_family_info (struct family_info *proc_info); 87 | 88 | #ifdef x64_BIT 89 | void get_vendor (char *vendor_string); 90 | #endif 91 | 92 | int turbo_status (); 93 | double cpufreq_info(); 94 | void get_familyinformation (struct family_info *proc_info); 95 | 96 | double estimate_MHz (); 97 | 98 | uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, 99 | unsigned int lowbit, int* error_indx); 100 | 101 | uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data, int* error_indx); 102 | 103 | 104 | #ifdef USE_INTEL_CPUID 105 | void get_CPUs_info (unsigned int *num_Logical_OS, 106 | unsigned int *num_Logical_process, 107 | unsigned int *num_Processor_Core, 108 | unsigned int *num_Physical_Socket); 109 | 110 | #endif 111 | 112 | int get_number_of_present_cpu(); 113 | void get_candidate_cores(struct cpu_heirarchy_info* chi); 114 | void get_online_cpus(struct cpu_heirarchy_info* chi); 115 | void get_siblings_list(struct cpu_heirarchy_info* chi); 116 | void get_package_ids(struct cpu_heirarchy_info* chi); 117 | void print_cpu_list(struct cpu_heirarchy_info chi); 118 | void construct_cpu_hierarchy(struct cpu_heirarchy_info *chi); 119 | void Print_Information_Processor(); 120 | void Test_Or_Make_MSR_DEVICE_FILES(); 121 | 122 | 123 | int check_and_return_processor(char*strinfo); 124 | int check_and_return_physical_id(char*strinfo); 125 | void construct_sibling_list(struct cpu_heirarchy_info* chi); 126 | void construct_socket_information(struct cpu_heirarchy_info* chi,struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1); 127 | void print_socket_information(struct cpu_socket_info* socket); 128 | void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi); 129 | void print_CPU_Heirarchy(struct cpu_heirarchy_info chi); 130 | int in_core_list(int ii,int* core_list); 131 | void Print_Version_Information(); 132 | 133 | int num_msr(); 134 | int bit_width_PMCx(); 135 | #define SET_ONLINE_ARRAY_MINUS1(online_cpus) {for(i=0;i<32;i++) online_cpus[i]=-1;} 136 | #define SET_ONLINE_ARRAY_PLUS1(online_cpus) {for(i=0;i<32;i++) online_cpus[i]=1;} 137 | 138 | #define SET_IF_TRUE(error_indx,a,b) if(error_indx) a=b; 139 | #define CONTINUE_IF_TRUE(cond) if(cond) continue; 140 | #define RETURN_IF_TRUE(cond) if(cond) return; 141 | 142 | //due to the fact that sometimes 100.0>100, the below macro checks till 101 143 | #define THRESHOLD_BETWEEN_0_100(cond) (cond>=-1 && cond <=101 && !isinf(cond) && !isnan(cond))? cond: __builtin_inf() 144 | 145 | //due to the fact that sometimes 100.0>100, the below macro checks till 101 146 | #define IS_THIS_BETWEEN_0_100(cond) (cond>=-1 && cond <=101 && !isinf(cond) && !isnan(cond))? 1: 0 147 | 148 | #define THRESHOLD_BETWEEN_0_6000(cond) (cond>=0 && cond <=10000)? cond: __builtin_inf() 149 | -------------------------------------------------------------------------------- /src/i7z.h: -------------------------------------------------------------------------------- 1 | //i7z.h 2 | /* ----------------------------------------------------------------------- * 3 | * 4 | * Copyright 2009 Abhishek Jaiantilal 5 | * 6 | * Under GPL v2 7 | * 8 | * modified for ivy bridge May 2013 9 | * Daniel McLellan 10 | * 11 | * ----------------------------------------------------------------------- */ 12 | 13 | #include 14 | #include 15 | 16 | #define MAX_PROCESSORS 128 17 | #define MAX_HI_PROCESSORS MAX_PROCESSORS 18 | #define MAX_SK_PROCESSORS (MAX_PROCESSORS/4) 19 | 20 | struct processors{ 21 | bool nehalem; 22 | bool sandy_bridge; 23 | bool ivy_bridge; 24 | bool haswell; 25 | bool broadwell; 26 | bool skylake; 27 | bool koby_lake; 28 | }; 29 | 30 | struct program_options{ 31 | int logging; //0=no logging, 1=logging, 2=appending 32 | bool quiet; 33 | bool use_ncurses; 34 | int templogging; 35 | int cstatelogging; 36 | //always put variables before the below structure, something fishy going on and the variable is reset 37 | struct processors proc_version; 38 | }; 39 | 40 | void init_ncurses(); 41 | 42 | /// Logging Functions 43 | void logOpenFile_single(); 44 | void logCloseFile_single(); 45 | void logCpuFreq_single(float value); 46 | 47 | void logOpenFile_dual(int); 48 | void logCloseFile_dual(int); 49 | void logCpuFreq_dual(float,int); 50 | void logCpuFreq_dual_d(int, int); 51 | void logCpuFreq_dual_ts(struct timespec *value, int) ; 52 | 53 | void logCpuCstates_single(float value); 54 | void logCpuCstates_single_c(char* value); 55 | //void logCpuCstates_single_d(int value); 56 | void logCpuCstates_single_ts(struct timespec *value) ; 57 | 58 | void logCpuCstates_dual(float value, int); 59 | void logCpuCstates_dual_c(char* value, int); 60 | void logCpuCstates_dual_ts(struct timespec *value, int) ; 61 | 62 | void debug (bool quiet, char* message); 63 | void print_model (bool quiet, int model); 64 | void error (char *message); 65 | 66 | struct cpu_hierarchy_info { 67 | int max_online_cpu; 68 | int num_sockets; 69 | int sibling_num[MAX_HI_PROCESSORS]; 70 | int processor_num[MAX_HI_PROCESSORS]; 71 | int package_num[MAX_HI_PROCESSORS]; 72 | int coreid_num[MAX_HI_PROCESSORS]; 73 | int display_cores[MAX_HI_PROCESSORS]; 74 | bool HT; 75 | }; 76 | 77 | struct cpu_socket_info { 78 | int max_cpu; 79 | int socket_num; 80 | int processor_num[MAX_SK_PROCESSORS]; 81 | int num_physical_cores; 82 | int num_logical_cores; 83 | }; 84 | 85 | struct family_info 86 | { 87 | char stepping; 88 | char model; 89 | char family; 90 | char processor_type; 91 | //char extended_model; 92 | int extended_family; 93 | }; 94 | 95 | //read TSC() code for 32 and 64-bit 96 | //http://www.mcs.anl.gov/~kazutomo/rdtsc.html 97 | 98 | #ifndef __LP64__ // 32 bit 99 | static __inline__ unsigned long long int 100 | rdtsc () 101 | { 102 | unsigned long long int x; 103 | __asm__ volatile (".byte 0x0f, 0x31":"=A" (x)); 104 | return x; 105 | } 106 | #else // 64 bit 107 | static __inline__ unsigned long long 108 | rdtsc (void) 109 | { 110 | unsigned hi, lo; 111 | __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); 112 | return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); 113 | } 114 | #endif 115 | 116 | 117 | void print_family_info (struct family_info *proc_info); 118 | 119 | //void get_vendor (char *vendor_string); 120 | 121 | int turbo_status (); 122 | double cpufreq_info(); 123 | //void get_familyinformation (struct family_info *proc_info); 124 | 125 | double estimate_MHz (); 126 | 127 | uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, 128 | unsigned int lowbit, int* error_indx); 129 | 130 | uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data); 131 | 132 | int get_number_of_present_cpu(); 133 | int get_intel_model(char model); 134 | void get_candidate_cores(struct cpu_hierarchy_info* chi); 135 | void get_online_cpus(struct cpu_hierarchy_info* chi); 136 | void get_siblings_list(struct cpu_hierarchy_info* chi); 137 | void get_package_ids(struct cpu_hierarchy_info* chi); 138 | void print_cpu_list(struct cpu_hierarchy_info chi); 139 | void construct_cpu_hierarchy(struct cpu_hierarchy_info *chi); 140 | void Print_Information_Processor(bool*, bool*, bool*); 141 | void Test_Or_Make_MSR_DEVICE_FILES(); 142 | 143 | 144 | int check_and_return_processor(char*strinfo); 145 | int check_and_return_physical_id(char*strinfo); 146 | void construct_sibling_list(struct cpu_hierarchy_info* chi); 147 | void construct_socket_information(struct cpu_hierarchy_info* chi, 148 | struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1, 149 | int, int); 150 | void print_socket_information(struct cpu_socket_info* socket); 151 | void construct_CPU_Hierarchy_info(struct cpu_hierarchy_info* chi); 152 | void print_CPU_Hierarchy(struct cpu_hierarchy_info chi); 153 | int in_core_list(int ii,int* core_list); 154 | bool file_exists(char*); 155 | 156 | #define SET_ONLINE_ARRAY_MINUS1(online_cpus) {int iii;for(iii=0;iii100, the below macro checks till 101 164 | #define THRESHOLD_BETWEEN_0_100(cond) (cond>=-1 && cond <=125 && !isinf(cond) && !isnan(cond))? cond: __builtin_inf() 165 | 166 | //due to the fact that sometimes 100.0>100, the below macro checks till 101 167 | #define IS_THIS_BETWEEN_0_100(cond) (cond>=-1 && cond <=125 && !isinf(cond) && !isnan(cond))? 0: 1 168 | 169 | #define THRESHOLD_BETWEEN_0_6000(cond) (cond>=0 && cond <=10000)? cond: __builtin_inf() 170 | -------------------------------------------------------------------------------- /src/i7z.c: -------------------------------------------------------------------------------- 1 | //i7z.c 2 | /* ----------------------------------------------------------------------- * 3 | * 4 | * Copyright 2009 Abhishek Jaiantilal 5 | * 6 | * Under GPL v2 7 | * 8 | * ----------------------------------------------------------------------- */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "getopt.h" 23 | #include "i7z.h" 24 | 25 | struct program_options prog_options; 26 | 27 | int Single_Socket(); 28 | int Dual_Socket(); 29 | 30 | int socket_0_num=0, socket_1_num=1; 31 | void atexit_runsttysane() 32 | { 33 | printf("Quitting i7z\n"); 34 | system("stty sane"); 35 | } 36 | 37 | void modprobing_msr() 38 | { 39 | system("modprobe msr"); 40 | } 41 | 42 | #define MAX_FILENAME_LENGTH 1000 43 | 44 | int main (int argc, char **argv) 45 | { 46 | atexit(atexit_runsttysane); 47 | 48 | //char log_file_name[MAX_FILENAME_LENGTH], log_file_name2[MAX_FILENAME_LENGTH+3]; 49 | prog_options.logging=0; //0=no logging, 1=logging, 2=appending 50 | prog_options.quiet = false; 51 | prog_options.use_ncurses = true; 52 | 53 | struct cpu_hierarchy_info chi; 54 | struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; 55 | struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; 56 | 57 | 58 | int c; 59 | bool presupplied_socket_info = false; 60 | 61 | static struct option long_options[]= 62 | { 63 | {"write", required_argument, 0, 'w'}, 64 | {"socket0", required_argument,0 ,'z'}, 65 | {"socket1", required_argument,0 ,'y'}, 66 | {"logfile", required_argument,0,'l'}, 67 | {"help", no_argument, 0, 'h'}, 68 | {"nogui", no_argument, 0, 'n'}, 69 | {"quiet", no_argument, 0, 'q'} 70 | }; 71 | 72 | prog_options.logging = 0; 73 | while(1) 74 | { 75 | int option_index = 0; 76 | c = getopt_long(argc, argv,"w:z:y:l:hn", long_options, &option_index); 77 | if (c==-1) 78 | break; 79 | switch(c) 80 | { 81 | case 'z': 82 | socket_0_num = atoi(optarg); 83 | presupplied_socket_info = true; 84 | printf("Socket_0 information will be about socket %d\n", socket_0.socket_num); 85 | break; 86 | case 'y': 87 | socket_1_num = atoi(optarg); 88 | presupplied_socket_info = true; 89 | printf("Socket_1 information will be about socket %d\n", socket_1.socket_num); 90 | break; 91 | case 'w': 92 | //printf("write options specified %s\n", optarg); 93 | if (strcmp("l",optarg)==0) 94 | { 95 | prog_options.logging = 1; 96 | printf("Logging is ON and set to replace\n"); 97 | } 98 | if (strcmp("a",optarg)==0) 99 | { 100 | prog_options.logging = 2; 101 | printf("Logging is ON and set to append\n"); 102 | } 103 | break; 104 | case 'q': 105 | prog_options.quiet = true; 106 | break; 107 | /* 108 | case 'l': 109 | strncpy(log_file_name, optarg, MAX_FILENAME_LENGTH-3); 110 | strcpy(log_file_name2, log_file_name); 111 | strcat(log_file_name2, "_%d"); 112 | CPU_FREQUENCY_LOGGING_FILE_single = log_file_name; 113 | CPU_FREQUENCY_LOGGING_FILE_dual = log_file_name2; 114 | printf("Logging frequencies to %s for single sockets, %s for dual sockets(0,1 for multiple sockets)\n", prog_options.CPU_FREQUENCY_LOGGING_FILE_single, prog_options.CPU_FREQUENCY_LOGGING_FILE_dual); 115 | break; 116 | */ 117 | case 'n': 118 | prog_options.use_ncurses = false; 119 | printf("Not Spawning the GUI\n"); 120 | break; 121 | 122 | case 'h': 123 | printf("\ni7z Tool Supports the following functions:\n"); 124 | printf("Append to a log file: "); 125 | printf("%c[%d;%d;%dm./i7z --write a ", 0x1B,1,31,40); 126 | printf("%c[%dm[OR] ",0x1B,0); 127 | printf("%c[%d;%d;%dm./i7z -w a\n", 0x1B,1,31,40); 128 | printf("%c[%dm",0x1B,0); 129 | 130 | printf("Replacement instead of Append: "); 131 | printf("%c[%d;%d;%dm./i7z --write l ", 0x1B,1,31,40); 132 | printf("%c[%dm[OR]", 0x1B,0); 133 | printf(" %c[%d;%d;%dm./i7z -w l\n", 0x1B,1,31,40); 134 | printf("%c[%dm",0x1B,0); 135 | 136 | //printf("Default log file name is %s (single socket) or %s (dual socket)\n", CPU_FREQUENCY_LOGGING_FILE_single, CPU_FREQUENCY_LOGGING_FILE_dual); 137 | //printf("Specifying a different log file: "); 138 | //printf("%c[%d;%d;%dm./i7z --logfile filename ", 0x1B,1,31,40); 139 | printf("%c[%dm[OR] ", 0x1B,0); 140 | printf("%c[%d;%d;%dm./i7z -l filename\n", 0x1B,1,31,40); 141 | printf("%c[%dm",0x1B,0); 142 | printf("Specifying a particular socket to print: %c[%d;%d;%dm./i7z --socket0 X \n", 0x1B,1,31,40); 143 | printf("%c[%dm",0x1B,0); 144 | printf("In order to print to a second socket use: %c[%d;%d;%dm./i7z --socket1 X \n", 0x1B,1,31,40); 145 | printf("%c[%dm",0x1B,0); 146 | printf("To turn the ncurses GUI off use: %c[%d;%d;%dm./i7z --nogui\n", 0x1B, 1, 31, 40); 147 | printf("%c[%dm",0x1B,0); 148 | 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); 149 | printf("%c[%dm",0x1B,0); 150 | 151 | exit(1); 152 | break; 153 | } 154 | } 155 | 156 | Print_Information_Processor (&prog_options.proc_version.nehalem, &prog_options.proc_version.sandy_bridge, &prog_options.proc_version.haswell); 157 | 158 | Test_Or_Make_MSR_DEVICE_FILES (); 159 | modprobing_msr(); 160 | 161 | construct_CPU_Hierarchy_info(&chi); 162 | construct_sibling_list(&chi); 163 | print_CPU_Hierarchy(chi); 164 | construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); 165 | print_socket_information(&socket_0); 166 | print_socket_information(&socket_1); 167 | 168 | if (!presupplied_socket_info){ 169 | if (socket_0.max_cpu>0 && socket_1.max_cpu>0) { 170 | //Path for Dual Socket Code 171 | printf("i7z DEBUG: Dual Socket Detected\n\r"); 172 | //Dual_Socket(&prog_options); 173 | Dual_Socket(); 174 | } else { 175 | //Path for Single Socket Code 176 | printf("i7z DEBUG: Single Socket Detected\n\r"); 177 | //Single_Socket(&prog_options); 178 | Single_Socket(); 179 | } 180 | } else { 181 | Dual_Socket(); 182 | } 183 | return(1); 184 | } 185 | -------------------------------------------------------------------------------- /scripts/cpuinfo.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "string.h" 3 | #include "stdlib.h" 4 | #include "assert.h" 5 | #define MAX_PROCESSORS 32 6 | #define bool int 7 | #define false 0 8 | #define true 1 9 | 10 | #define MAX_HI_PROCESSORS MAX_PROCESSORS 11 | 12 | struct cpu_heirarchy_info { 13 | int max_online_cpu; 14 | int num_sockets; 15 | int sibling_num[MAX_HI_PROCESSORS]; 16 | int processor_num[MAX_HI_PROCESSORS]; 17 | int package_num[MAX_HI_PROCESSORS]; 18 | int coreid_num[MAX_HI_PROCESSORS]; 19 | int display_cores[MAX_HI_PROCESSORS]; 20 | bool HT; 21 | }; 22 | 23 | #define MAX_SK_PROCESSORS (MAX_PROCESSORS/4) 24 | 25 | struct cpu_socket_info { 26 | int max_cpu; 27 | int socket_num; 28 | int processor_num[MAX_SK_PROCESSORS]; 29 | int num_physical_cores; 30 | int num_logical_cores; 31 | }; 32 | 33 | int check_and_return_processor(char*strinfo) 34 | { 35 | char *t1; 36 | if (strstr(strinfo,"processor") !=NULL) { 37 | strtok(strinfo,":"); 38 | t1 = strtok(NULL, " "); 39 | return(atoi(t1)); 40 | } else { 41 | return(-1); 42 | } 43 | } 44 | 45 | int check_and_return_physical_id(char*strinfo) 46 | { 47 | char *t1; 48 | if (strstr(strinfo,"physical id") !=NULL) { 49 | strtok(strinfo,":"); 50 | t1 = strtok(NULL, " "); 51 | return(atoi(t1)); 52 | } else { 53 | return(-1); 54 | } 55 | } 56 | 57 | int check_and_return_core_id(char*strinfo) 58 | { 59 | char *t1; 60 | if (strstr(strinfo,"core id") !=NULL) { 61 | strtok(strinfo,":"); 62 | t1 = strtok(NULL, " "); 63 | return(atoi(t1)); 64 | } else { 65 | return(-1); 66 | } 67 | } 68 | 69 | void construct_sibling_list(struct cpu_heirarchy_info* chi) 70 | { 71 | int i,j,core_id,socket_id; 72 | for (i=0;i< chi->max_online_cpu ;i++) { 73 | assert(i < MAX_HI_PROCESSORS); 74 | chi->sibling_num[i]=-1; 75 | } 76 | 77 | chi->HT=false; 78 | for (i=0;i< chi->max_online_cpu ;i++) { 79 | assert(i < MAX_HI_PROCESSORS); 80 | core_id = chi->coreid_num[i]; 81 | socket_id = chi->package_num[i]; 82 | for (j=i+1;j< chi->max_online_cpu ;j++) { 83 | assert(j < MAX_HI_PROCESSORS); 84 | if (chi->coreid_num[j] == core_id && chi->package_num[j] == socket_id) { 85 | chi->sibling_num[j] = i; 86 | chi->sibling_num[i] = j; 87 | chi->display_cores[i] = 1; 88 | chi->display_cores[j] = -1; 89 | chi->HT=true; 90 | continue; 91 | } 92 | } 93 | } 94 | //for cores that donot have a sibling put in 1 95 | for (i=0;i< chi->max_online_cpu ;i++) { 96 | assert(i < MAX_HI_PROCESSORS); 97 | if (chi->sibling_num[i] ==-1) 98 | chi->display_cores[i] = 1; 99 | } 100 | } 101 | 102 | void construct_socket_information(struct cpu_heirarchy_info* chi,struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1) 103 | { 104 | 105 | int i; 106 | char socket_1_list[200]="", socket_0_list[200]=""; 107 | 108 | for (i=0;i< chi->max_online_cpu ;i++) { 109 | assert(i < MAX_HI_PROCESSORS); 110 | if (chi->display_cores[i]!=-1) { 111 | if (chi->package_num[i]==0) { 112 | assert(socket_0->max_cpu < MAX_SK_PROCESSORS); 113 | socket_0->processor_num[socket_0->max_cpu]=chi->processor_num[i]; 114 | socket_0->max_cpu++; 115 | socket_0->num_physical_cores++; 116 | socket_0->num_logical_cores++; 117 | } 118 | if (chi->package_num[i]==1) { 119 | assert(socket_1->max_cpu < MAX_SK_PROCESSORS); 120 | socket_1->processor_num[socket_1->max_cpu]=chi->processor_num[i]; 121 | socket_1->max_cpu++; 122 | socket_1->num_physical_cores++; 123 | socket_1->num_logical_cores++; 124 | } 125 | } else { 126 | if (chi->package_num[i]==0) { 127 | socket_0->num_logical_cores++; 128 | } 129 | if (chi->package_num[i]==1) { 130 | socket_1->num_logical_cores++; 131 | } 132 | } 133 | } 134 | } 135 | 136 | void print_socket_information(struct cpu_socket_info* socket) 137 | { 138 | int i; 139 | char socket_list[200]=""; 140 | 141 | for (i=0;i< socket->max_cpu ;i++) { 142 | assert(i < MAX_SK_PROCESSORS); 143 | if (socket->processor_num[i]!=-1) { 144 | sprintf(socket_list,"%s%d,",socket_list,socket->processor_num[i]); 145 | } 146 | } 147 | 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); 148 | } 149 | 150 | void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi) 151 | { 152 | int i; 153 | FILE *fp = fopen("/proc/cpuinfo","r"); 154 | char strinfo[200]; 155 | 156 | int processor_num, physicalid_num, coreid_num; 157 | int it_processor_num=-1, it_physicalid_num=-1, it_coreid_num=-1; 158 | int tmp_processor_num, tmp_physicalid_num, tmp_coreid_num; 159 | int old_processor_num=-1; 160 | 161 | 162 | if (fp!=NULL) { 163 | while ( fgets(strinfo,200,fp) != NULL) { 164 | printf(strinfo); 165 | tmp_processor_num = check_and_return_processor(strinfo); 166 | tmp_physicalid_num = check_and_return_physical_id(strinfo); 167 | tmp_coreid_num = check_and_return_core_id(strinfo); 168 | 169 | 170 | if (tmp_processor_num != -1) { 171 | it_processor_num++; 172 | processor_num = tmp_processor_num; 173 | assert(it_processor_num < MAX_HI_PROCESSORS); 174 | chi->processor_num[it_processor_num] = processor_num; 175 | } 176 | if (tmp_physicalid_num != -1) { 177 | it_physicalid_num++; 178 | physicalid_num = tmp_physicalid_num; 179 | assert(it_physicalid_num < MAX_HI_PROCESSORS); 180 | chi->package_num[it_physicalid_num] = physicalid_num; 181 | } 182 | if (tmp_coreid_num != -1) { 183 | it_coreid_num++; 184 | coreid_num = tmp_coreid_num; 185 | assert(it_coreid_num < MAX_HI_PROCESSORS); 186 | chi->coreid_num[it_coreid_num] = coreid_num; 187 | } 188 | if (processor_num != old_processor_num) { 189 | old_processor_num = processor_num; 190 | } 191 | } 192 | } 193 | chi->max_online_cpu = it_processor_num+1; 194 | 195 | } 196 | 197 | void print_CPU_Heirarchy(struct cpu_heirarchy_info chi) 198 | { 199 | int i; 200 | printf("Legend: processor number is the processor number as linux knows, socket number is the socket number,\n \ 201 | coreid number is the core with which this processor is associated, thus for HT machines there will be 2 processors\n\ 202 | 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\ 203 | if i am already showing information about a core then i dont need to show information about the sibling\n"); 204 | for (i=0;i < chi.max_online_cpu;i++) { 205 | assert(i < MAX_HI_PROCESSORS); 206 | printf("--[%d] Processor number %d\n",i,chi.processor_num[i]); 207 | printf("--[%d] Socket number/Sibling number %d,%d\n",i,chi.package_num[i],chi.sibling_num[i]); 208 | printf("--[%d] Core id number %d\n",i,chi.coreid_num[i]); 209 | printf("--[%d] Display core %d\n\n",i,chi.display_cores[i]); 210 | } 211 | } 212 | 213 | int main() 214 | { 215 | struct cpu_heirarchy_info chi; 216 | struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; 217 | struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; 218 | 219 | construct_CPU_Heirarchy_info(&chi); 220 | construct_sibling_list(&chi); 221 | print_CPU_Heirarchy(chi); 222 | construct_socket_information(&chi, &socket_0, &socket_1); 223 | print_socket_information(&socket_0); 224 | print_socket_information(&socket_1); 225 | 226 | } 227 | -------------------------------------------------------------------------------- /src/GUI/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Makefile for building: i7z_GUI 3 | # Generated by qmake (2.01a) (Qt 4.8.4) on: Fri Sep 13 10:41:57 2013 4 | # Project: i7z_GUI.pro 5 | # Template: app 6 | # Command: /usr/lib/x86_64-linux-gnu/qt4/bin/qmake -o Makefile i7z_GUI.pro 7 | ############################################################################# 8 | 9 | ####### Compiler, tools and options 10 | 11 | CC = gcc 12 | CXX = g++ 13 | DEFINES = -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED 14 | CFLAGS = -m64 -pipe -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves -g -Wall -W -D_REENTRANT $(DEFINES) 15 | CXXFLAGS = -m64 -pipe -v -fno-schedule-insns2 -fno-schedule-insns -fno-inline-small-functions -fno-caller-saves -g -Wall -W -D_REENTRANT $(DEFINES) 16 | 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. 17 | LINK = g++ 18 | LFLAGS = -m64 19 | LIBS = $(SUBLIBS) -L/usr/lib/x86_64-linux-gnu -lQtGui -lQtCore -lpthread 20 | AR = ar cqs 21 | RANLIB = 22 | QMAKE = /usr/lib/x86_64-linux-gnu/qt4/bin/qmake 23 | TAR = tar -cf 24 | COMPRESS = gzip -9f 25 | COPY = cp -f 26 | SED = sed 27 | COPY_FILE = $(COPY) 28 | COPY_DIR = $(COPY) -r 29 | STRIP = strip 30 | INSTALL_FILE = install -m 644 -p 31 | INSTALL_DIR = $(COPY_DIR) 32 | INSTALL_PROGRAM = install -m 755 -p 33 | DEL_FILE = rm -f 34 | SYMLINK = ln -f -s 35 | DEL_DIR = rmdir 36 | MOVE = mv -f 37 | CHK_DIR_EXISTS= test -d 38 | MKDIR = mkdir -p 39 | 40 | ####### Output directory 41 | 42 | OBJECTS_DIR = ./ 43 | 44 | ####### Files 45 | 46 | SOURCES = i7z_GUI.cpp 47 | OBJECTS = i7z_GUI.o 48 | DIST = /usr/share/qt4/mkspecs/common/unix.conf \ 49 | /usr/share/qt4/mkspecs/common/linux.conf \ 50 | /usr/share/qt4/mkspecs/common/gcc-base.conf \ 51 | /usr/share/qt4/mkspecs/common/gcc-base-unix.conf \ 52 | /usr/share/qt4/mkspecs/common/g++-base.conf \ 53 | /usr/share/qt4/mkspecs/common/g++-unix.conf \ 54 | /usr/share/qt4/mkspecs/qconfig.pri \ 55 | /usr/share/qt4/mkspecs/features/qt_functions.prf \ 56 | /usr/share/qt4/mkspecs/features/qt_config.prf \ 57 | /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ 58 | /usr/share/qt4/mkspecs/features/default_pre.prf \ 59 | /usr/share/qt4/mkspecs/features/debug.prf \ 60 | /usr/share/qt4/mkspecs/features/default_post.prf \ 61 | /usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \ 62 | /usr/share/qt4/mkspecs/features/warn_on.prf \ 63 | /usr/share/qt4/mkspecs/features/qt.prf \ 64 | /usr/share/qt4/mkspecs/features/unix/thread.prf \ 65 | /usr/share/qt4/mkspecs/features/moc.prf \ 66 | /usr/share/qt4/mkspecs/features/resources.prf \ 67 | /usr/share/qt4/mkspecs/features/uic.prf \ 68 | /usr/share/qt4/mkspecs/features/yacc.prf \ 69 | /usr/share/qt4/mkspecs/features/lex.prf \ 70 | /usr/share/qt4/mkspecs/features/include_source_dir.prf \ 71 | i7z_GUI.pro 72 | QMAKE_TARGET = i7z_GUI 73 | DESTDIR = 74 | TARGET = i7z_GUI 75 | 76 | first: all 77 | ####### Implicit rules 78 | 79 | .SUFFIXES: .o .c .cpp .cc .cxx .C 80 | 81 | .cpp.o: 82 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" 83 | 84 | .cc.o: 85 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" 86 | 87 | .cxx.o: 88 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" 89 | 90 | .C.o: 91 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" 92 | 93 | .c.o: 94 | $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" 95 | 96 | ####### Build rules 97 | 98 | all: Makefile $(TARGET) 99 | 100 | $(TARGET): $(OBJECTS) 101 | $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) 102 | { test -n "$(DESTDIR)" && DESTDIR="$(DESTDIR)" || DESTDIR=.; } && test $$(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $$DESTDIR" -ex quit '$(TARGET)' && test -f $(TARGET).gdb-index && objcopy --add-section '.gdb_index=$(TARGET).gdb-index' --set-section-flags '.gdb_index=readonly' '$(TARGET)' '$(TARGET)' && rm -f $(TARGET).gdb-index || true 103 | 104 | Makefile: i7z_GUI.pro /usr/share/qt4/mkspecs/linux-g++-64/qmake.conf /usr/share/qt4/mkspecs/common/unix.conf \ 105 | /usr/share/qt4/mkspecs/common/linux.conf \ 106 | /usr/share/qt4/mkspecs/common/gcc-base.conf \ 107 | /usr/share/qt4/mkspecs/common/gcc-base-unix.conf \ 108 | /usr/share/qt4/mkspecs/common/g++-base.conf \ 109 | /usr/share/qt4/mkspecs/common/g++-unix.conf \ 110 | /usr/share/qt4/mkspecs/qconfig.pri \ 111 | /usr/share/qt4/mkspecs/features/qt_functions.prf \ 112 | /usr/share/qt4/mkspecs/features/qt_config.prf \ 113 | /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ 114 | /usr/share/qt4/mkspecs/features/default_pre.prf \ 115 | /usr/share/qt4/mkspecs/features/debug.prf \ 116 | /usr/share/qt4/mkspecs/features/default_post.prf \ 117 | /usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \ 118 | /usr/share/qt4/mkspecs/features/warn_on.prf \ 119 | /usr/share/qt4/mkspecs/features/qt.prf \ 120 | /usr/share/qt4/mkspecs/features/unix/thread.prf \ 121 | /usr/share/qt4/mkspecs/features/moc.prf \ 122 | /usr/share/qt4/mkspecs/features/resources.prf \ 123 | /usr/share/qt4/mkspecs/features/uic.prf \ 124 | /usr/share/qt4/mkspecs/features/yacc.prf \ 125 | /usr/share/qt4/mkspecs/features/lex.prf \ 126 | /usr/share/qt4/mkspecs/features/include_source_dir.prf \ 127 | /usr/lib/x86_64-linux-gnu/libQtGui.prl \ 128 | /usr/lib/x86_64-linux-gnu/libQtCore.prl 129 | $(QMAKE) -o Makefile i7z_GUI.pro 130 | /usr/share/qt4/mkspecs/common/unix.conf: 131 | /usr/share/qt4/mkspecs/common/linux.conf: 132 | /usr/share/qt4/mkspecs/common/gcc-base.conf: 133 | /usr/share/qt4/mkspecs/common/gcc-base-unix.conf: 134 | /usr/share/qt4/mkspecs/common/g++-base.conf: 135 | /usr/share/qt4/mkspecs/common/g++-unix.conf: 136 | /usr/share/qt4/mkspecs/qconfig.pri: 137 | /usr/share/qt4/mkspecs/features/qt_functions.prf: 138 | /usr/share/qt4/mkspecs/features/qt_config.prf: 139 | /usr/share/qt4/mkspecs/features/exclusive_builds.prf: 140 | /usr/share/qt4/mkspecs/features/default_pre.prf: 141 | /usr/share/qt4/mkspecs/features/debug.prf: 142 | /usr/share/qt4/mkspecs/features/default_post.prf: 143 | /usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf: 144 | /usr/share/qt4/mkspecs/features/warn_on.prf: 145 | /usr/share/qt4/mkspecs/features/qt.prf: 146 | /usr/share/qt4/mkspecs/features/unix/thread.prf: 147 | /usr/share/qt4/mkspecs/features/moc.prf: 148 | /usr/share/qt4/mkspecs/features/resources.prf: 149 | /usr/share/qt4/mkspecs/features/uic.prf: 150 | /usr/share/qt4/mkspecs/features/yacc.prf: 151 | /usr/share/qt4/mkspecs/features/lex.prf: 152 | /usr/share/qt4/mkspecs/features/include_source_dir.prf: 153 | /usr/lib/x86_64-linux-gnu/libQtGui.prl: 154 | /usr/lib/x86_64-linux-gnu/libQtCore.prl: 155 | qmake: FORCE 156 | @$(QMAKE) -o Makefile i7z_GUI.pro 157 | 158 | dist: 159 | @$(CHK_DIR_EXISTS) .tmp/i7z_GUI1.0.0 || $(MKDIR) .tmp/i7z_GUI1.0.0 160 | $(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 161 | 162 | 163 | clean:compiler_clean 164 | -$(DEL_FILE) $(OBJECTS) 165 | -$(DEL_FILE) *~ core *.core 166 | 167 | 168 | ####### Sub-libraries 169 | 170 | distclean: clean 171 | -$(DEL_FILE) $(TARGET) 172 | -$(DEL_FILE) Makefile 173 | 174 | 175 | check: first 176 | 177 | mocclean: compiler_moc_header_clean compiler_moc_source_clean 178 | 179 | mocables: compiler_moc_header_make_all compiler_moc_source_make_all 180 | 181 | compiler_moc_header_make_all: 182 | compiler_moc_header_clean: 183 | compiler_rcc_make_all: 184 | compiler_rcc_clean: 185 | compiler_image_collection_make_all: qmake_image_collection.cpp 186 | compiler_image_collection_clean: 187 | -$(DEL_FILE) qmake_image_collection.cpp 188 | compiler_moc_source_make_all: i7z_GUI.moc 189 | compiler_moc_source_clean: 190 | -$(DEL_FILE) i7z_GUI.moc 191 | i7z_GUI.moc: ../helper_functions.c \ 192 | ../i7z.h \ 193 | i7z_GUI.cpp 194 | /usr/lib/x86_64-linux-gnu/qt4/bin/moc $(DEFINES) $(INCPATH) i7z_GUI.cpp -o i7z_GUI.moc 195 | 196 | compiler_uic_make_all: 197 | compiler_uic_clean: 198 | compiler_yacc_decl_make_all: 199 | compiler_yacc_decl_clean: 200 | compiler_yacc_impl_make_all: 201 | compiler_yacc_impl_clean: 202 | compiler_lex_make_all: 203 | compiler_lex_clean: 204 | compiler_clean: compiler_moc_source_clean 205 | 206 | ####### Compile 207 | 208 | i7z_GUI.o: i7z_GUI.cpp ../helper_functions.c \ 209 | ../i7z.h \ 210 | i7z_GUI.moc 211 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o i7z_GUI.o i7z_GUI.cpp 212 | 213 | ####### Install 214 | 215 | install: FORCE 216 | 217 | uninstall: FORCE 218 | 219 | FORCE: 220 | 221 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "i7z.h" 5 | #include "intel.h" 6 | 7 | extern struct program_options prog_options; 8 | 9 | char* report_addr = "github.com/afontenot/i7z"; 10 | 11 | char* CPU_FREQUENCY_LOGGING_FILE_single="cpu_freq_log.txt"; 12 | char* CPU_FREQUENCY_LOGGING_FILE_dual="cpu_freq_log_dual_%d.txt"; 13 | char* CSTATE_LOGGING_FILE_single="cpu_cstate_log.txt"; 14 | char* CSTATE_LOGGING_FILE_dual="cpu_cstate_log_dual_%d.txt"; 15 | 16 | void debug (bool quiet, char* message) { 17 | if (quiet) { 18 | return; 19 | } 20 | printf("i7z DEBUG: %s\n", message); 21 | } 22 | 23 | void error (char* message) { 24 | debug(false, message); 25 | } 26 | 27 | void print_model(bool quiet, int model) { 28 | switch (model) { 29 | case INTEL_NEHALEM: 30 | debug(quiet, "Detected i3/i5/i7 Nehalem"); 31 | break; 32 | case INTEL_WESTMERE: 33 | debug(quiet, "Detected i3/i5/i7 Westmere"); 34 | break; 35 | case INTEL_SANDYBRIDGE: 36 | debug(quiet, "Detected i3/i5/i7 Sandy Bridge"); 37 | break; 38 | case INTEL_HASWELL: 39 | debug(quiet, "Detected i3/i5/i7 Haswell"); 40 | break; 41 | case INTEL_BROADWELL: 42 | debug(quiet, "Detected i3/i5/i7 Broadwell"); 43 | break; 44 | case INTEL_SKYLAKE: 45 | debug(quiet, "Detected i3/i5/i7 Skylake"); 46 | break; 47 | case INTEL_KABYLAKE: 48 | debug(quiet, "Detected i3/i5/i7 Kabylake"); 49 | break; 50 | case INTEL_CANNONLAKE: 51 | debug(quiet, "Detected i3/i5/i7 Cannonlake (mobile)"); 52 | break; 53 | default: ; 54 | char output[100]; 55 | sprintf(output, "unknown processor! please report this to %s", report_addr); 56 | debug(quiet, output); 57 | break; 58 | } 59 | } 60 | 61 | // old log stuff TODO: condense this mess 62 | 63 | FILE *fp_log_file_freq; 64 | FILE *fp_log_file_freq_1, *fp_log_file_freq_2; 65 | 66 | FILE *fp_log_file_Cstates; 67 | FILE *fp_log_file_Cstates_1, *fp_log_file_Cstates_2; 68 | 69 | void logOpenFile_single() 70 | { 71 | if(prog_options.logging==1) { 72 | fp_log_file_freq = fopen(CPU_FREQUENCY_LOGGING_FILE_single,"w"); 73 | fp_log_file_Cstates = fopen(CSTATE_LOGGING_FILE_single,"w"); 74 | } else if(prog_options.logging==2) { 75 | fp_log_file_freq = fopen(CPU_FREQUENCY_LOGGING_FILE_single,"a"); 76 | fp_log_file_Cstates = fopen(CSTATE_LOGGING_FILE_single,"a"); 77 | } 78 | } 79 | 80 | void logCloseFile_single() 81 | { 82 | if(prog_options.logging!=0){ 83 | if(prog_options.logging==2) 84 | fprintf(fp_log_file_freq,"\n"); 85 | //the above line puts a \n after every freq is logged. 86 | fclose(fp_log_file_freq); 87 | 88 | fprintf(fp_log_file_Cstates,"\n"); 89 | //the above line puts a \n after every CSTATE is logged. 90 | fclose(fp_log_file_Cstates); 91 | 92 | } 93 | } 94 | 95 | // For dual socket make filename based on the socket number 96 | void logOpenFile_dual(int socket_num) 97 | { 98 | char str_file1[100]; 99 | snprintf(str_file1,100,CPU_FREQUENCY_LOGGING_FILE_dual,socket_num); 100 | 101 | char str_file2[100]; 102 | snprintf(str_file2,100,CSTATE_LOGGING_FILE_dual,socket_num); 103 | 104 | if(socket_num==0){ 105 | if(prog_options.logging==1) 106 | fp_log_file_freq_1 = fopen(str_file1,"w"); 107 | else if(prog_options.logging==2) 108 | fp_log_file_freq_1 = fopen(str_file1,"a"); 109 | } 110 | if(socket_num==1){ 111 | if(prog_options.logging==1) 112 | fp_log_file_freq_2 = fopen(str_file1,"w"); 113 | else if(prog_options.logging==2) 114 | fp_log_file_freq_2 = fopen(str_file1,"a"); 115 | } 116 | 117 | if(socket_num==0){ 118 | if(prog_options.logging==1) 119 | fp_log_file_Cstates_1 = fopen(str_file2,"w"); 120 | else if(prog_options.logging==2) 121 | fp_log_file_Cstates_1 = fopen(str_file2,"a"); 122 | } 123 | if(socket_num==1){ 124 | if(prog_options.logging==1) 125 | fp_log_file_Cstates_2 = fopen(str_file2,"w"); 126 | else if(prog_options.logging==2) 127 | fp_log_file_Cstates_2 = fopen(str_file2,"a"); 128 | } 129 | } 130 | 131 | void logCloseFile_dual(int socket_num) 132 | { 133 | if(socket_num==0){ 134 | if(prog_options.logging!=0){ 135 | if(prog_options.logging==2) 136 | fprintf(fp_log_file_freq_1,"\n"); 137 | //the above line puts a \n after every freq is logged. 138 | fclose(fp_log_file_freq_1); 139 | } 140 | } 141 | if(socket_num==1){ 142 | if(prog_options.logging!=0){ 143 | if(prog_options.logging==2) 144 | fprintf(fp_log_file_freq_2,"\n"); 145 | //the above line puts a \n after every freq is logged. 146 | fclose(fp_log_file_freq_2); 147 | } 148 | } 149 | 150 | 151 | if(socket_num==0){ 152 | if(prog_options.logging!=0){ 153 | if(prog_options.logging==2) 154 | fprintf(fp_log_file_Cstates_1,"\n"); 155 | //the above line puts a \n after every freq is logged. 156 | fclose(fp_log_file_Cstates_1); 157 | } 158 | } 159 | if(socket_num==1){ 160 | if(prog_options.logging!=0){ 161 | if(prog_options.logging==2) 162 | fprintf(fp_log_file_Cstates_2,"\n"); 163 | //the above line puts a \n after every freq is logged. 164 | fclose(fp_log_file_Cstates_2); 165 | } 166 | } 167 | } 168 | 169 | 170 | void logCpuFreq_single(float value) 171 | { 172 | //below when just logging 173 | if(prog_options.logging==1) { 174 | fprintf(fp_log_file_freq,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs 175 | } 176 | //below when appending 177 | if(prog_options.logging==2) { 178 | fprintf(fp_log_file_freq,"%f\t",value); 179 | } 180 | } 181 | 182 | void logCpuFreq_single_c(char* value) 183 | { 184 | //below when just logging 185 | if(prog_options.logging==1) { 186 | fprintf(fp_log_file_freq,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs 187 | } 188 | //below when appending 189 | if(prog_options.logging==2) { 190 | fprintf(fp_log_file_freq,"%s\t",value); 191 | } 192 | } 193 | 194 | void logCpuFreq_single_d(int value) 195 | { 196 | //below when just logging 197 | if(prog_options.logging==1) { 198 | fprintf(fp_log_file_freq,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs 199 | } 200 | //below when appending 201 | if(prog_options.logging==2) { 202 | fprintf(fp_log_file_freq,"%d\t",value); 203 | } 204 | } 205 | 206 | // fix for issue 48, suggested by Hakan 207 | void logCpuFreq_single_ts(struct timespec *value) //HW use timespec to avoid floating point overflow 208 | { 209 | //below when just logging 210 | if(prog_options.logging==1) { 211 | fprintf(fp_log_file_freq,"%ld.%.9ld\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 212 | } 213 | //below when appending 214 | if(prog_options.logging==2) { 215 | fprintf(fp_log_file_freq,"%ld.%.9ld\t",value->tv_sec,value->tv_nsec); 216 | } 217 | } 218 | 219 | 220 | void logCpuFreq_dual(float value,int socket_num) 221 | { 222 | if(socket_num==0){ 223 | //below when just logging 224 | if(prog_options.logging==1) 225 | fprintf(fp_log_file_freq_1,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs 226 | 227 | //below when appending 228 | if(prog_options.logging==2) 229 | fprintf(fp_log_file_freq_1,"%f\t",value); 230 | } 231 | if(socket_num==1){ 232 | //below when just logging 233 | if(prog_options.logging==1) 234 | fprintf(fp_log_file_freq_2,"%f\n",value); //newline, replace \n with \t to get everything separated with tabs 235 | 236 | //below when appending 237 | if(prog_options.logging==2) 238 | fprintf(fp_log_file_freq_2,"%f\t",value); 239 | } 240 | } 241 | 242 | void logCpuFreq_dual_c(char* value,int socket_num) 243 | { 244 | if(socket_num==0){ 245 | //below when just logging 246 | if(prog_options.logging==1) 247 | fprintf(fp_log_file_freq_1,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs 248 | 249 | //below when appending 250 | if(prog_options.logging==2) 251 | fprintf(fp_log_file_freq_1,"%s\t",value); 252 | } 253 | if(socket_num==1){ 254 | //below when just logging 255 | if(prog_options.logging==1) 256 | fprintf(fp_log_file_freq_2,"%s\n",value); //newline, replace \n with \t to get everything separated with tabs 257 | 258 | //below when appending 259 | if(prog_options.logging==2) 260 | fprintf(fp_log_file_freq_2,"%s\t",value); 261 | } 262 | } 263 | 264 | void logCpuFreq_dual_d(int value,int socket_num) 265 | { 266 | if(socket_num==0){ 267 | //below when just logging 268 | if(prog_options.logging==1) 269 | fprintf(fp_log_file_freq_1,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs 270 | 271 | //below when appending 272 | if(prog_options.logging==2) 273 | fprintf(fp_log_file_freq_1,"%d\t",value); 274 | } 275 | if(socket_num==1){ 276 | //below when just logging 277 | if(prog_options.logging==1) 278 | fprintf(fp_log_file_freq_2,"%d\n",value); //newline, replace \n with \t to get everything separated with tabs 279 | 280 | //below when appending 281 | if(prog_options.logging==2) 282 | fprintf(fp_log_file_freq_2,"%d\t",value); 283 | } 284 | } 285 | 286 | void logCpuFreq_dual_ts(struct timespec *value, int socket_num) //HW use timespec to avoid floating point overflow 287 | { 288 | if(socket_num==0){ 289 | //below when just logging 290 | if(prog_options.logging==1) 291 | fprintf(fp_log_file_freq_1,"%ld.%.9ld\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 292 | 293 | //below when appending 294 | if(prog_options.logging==2) 295 | fprintf(fp_log_file_freq_1,"%ld.%.9ld\t",value->tv_sec,value->tv_nsec); 296 | } 297 | if(socket_num==1){ 298 | //below when just logging 299 | if(prog_options.logging==1) 300 | fprintf(fp_log_file_freq_2,"%ld.%.9ld\n",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 301 | 302 | //below when appending 303 | if(prog_options.logging==2) 304 | fprintf(fp_log_file_freq_2,"%ld.%.9ld\t",value->tv_sec,value->tv_nsec); 305 | } 306 | } 307 | 308 | void logCpuCstates_single(float value) 309 | { 310 | //below when just logging 311 | if(prog_options.logging != 0) { 312 | fprintf(fp_log_file_Cstates,"%f",value); //newline, replace \n with \t to get everything separated with tabs 313 | } 314 | } 315 | 316 | void logCpuCstates_single_c(char* value) 317 | { 318 | //below when just logging 319 | if(prog_options.logging != 0) { 320 | fprintf(fp_log_file_Cstates,"%s",value); //newline, replace \n with \t to get everything separated with tabs 321 | } 322 | } 323 | 324 | void logCpuCstates_single_d(int value) 325 | { 326 | //below when just logging 327 | if(prog_options.logging != 0) { 328 | fprintf(fp_log_file_Cstates,"%d",value); //newline, replace \n with \t to get everything separated with tabs 329 | } 330 | } 331 | 332 | // fix for issue 48, suggested by Hakan 333 | void logCpuCstates_single_ts(struct timespec *value) //HW use timespec to avoid floating point overflow 334 | { 335 | //below when just logging 336 | if(prog_options.logging != 0) { 337 | fprintf(fp_log_file_Cstates,"%ld.%.9ld",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 338 | } 339 | } 340 | 341 | void logCpuCstates_dual(float value,int socket_num) 342 | { 343 | if(socket_num==0){ 344 | //below when just logging 345 | if(prog_options.logging != 0) 346 | fprintf(fp_log_file_Cstates_1,"%f",value); //newline, replace \n with \t to get everything separated with tabs 347 | } 348 | if(socket_num==1){ 349 | //below when just logging 350 | if(prog_options.logging != 0) 351 | fprintf(fp_log_file_Cstates_2,"%f",value); //newline, replace \n with \t to get everything separated with tabs 352 | } 353 | } 354 | 355 | void logCpuCstates_dual_c(char* value,int socket_num) 356 | { 357 | if(socket_num==0){ 358 | //below when just logging 359 | if(prog_options.logging != 0) 360 | fprintf(fp_log_file_Cstates_1,"%s",value); //newline, replace \n with \t to get everything separated with tabs 361 | } 362 | if(socket_num==1){ 363 | //below when just logging 364 | if(prog_options.logging != 0) 365 | fprintf(fp_log_file_Cstates_2,"%s",value); //newline, replace \n with \t to get everything separated with tabs 366 | } 367 | } 368 | 369 | void logCpuCstates_dual_d(int value,int socket_num) 370 | { 371 | if(socket_num==0){ 372 | //below when just logging 373 | if(prog_options.logging != 0) 374 | fprintf(fp_log_file_Cstates_1,"%d",value); //newline, replace \n with \t to get everything separated with tabs 375 | } 376 | if(socket_num==1){ 377 | //below when just logging 378 | if(prog_options.logging != 0) 379 | fprintf(fp_log_file_Cstates_2,"%d",value); //newline, replace \n with \t to get everything separated with tabs 380 | } 381 | } 382 | 383 | void logCpuCstates_dual_ts(struct timespec *value, int socket_num) //HW use timespec to avoid floating point overflow 384 | { 385 | if(socket_num==0){ 386 | //below when just logging 387 | if(prog_options.logging != 0) 388 | fprintf(fp_log_file_Cstates_1,"%ld.%.9ld",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 389 | } 390 | if(socket_num==1){ 391 | //below when just logging 392 | if(prog_options.logging != 0) 393 | fprintf(fp_log_file_Cstates_2,"%ld.%.9ld",value->tv_sec,value->tv_nsec); //newline, replace \n with \t to get everything separated with tabs 394 | } 395 | } 396 | 397 | 398 | -------------------------------------------------------------------------------- /scripts/i7z_rw_registers.rb: -------------------------------------------------------------------------------- 1 | #* ----------------------------------------------------------------------- * 2 | # * 3 | # * Under GPL v3 4 | # * written by Abhishek Jaiantilal 5 | # * much thanks to Antonio Meireles who suggested this idea & helped with testing 6 | # * run as sudo ruby i7z_rw_registers.rb 7 | # * 8 | # * ----------------------------------------------------------------------- */ 9 | 10 | #!/usr/bin/ruby 11 | 12 | def print_command_list() 13 | print "Do you need help? \n" 14 | print "Possible commands are \n" 15 | print "help : which will print this list again \n" 16 | print "turbo : which examines the turbo status \n" 17 | print "multiplier : examines the multipliers \n" 18 | print "power : which prints current wattage of the system\n" 19 | print "clock : allows for software clock modulation ( a form of throttling )\n" 20 | print "system : allows to print some system info\n" 21 | print "quit : which will quit the program or just do ctrl + c\n" 22 | end 23 | 24 | IA32_PERF_STATUS = 0x198 #read only 25 | IA32_PERF_CTL = 0x199 #read write 26 | IA32_MISC_ENABLE = 0x1a0 27 | 28 | def num_cores 29 | numcores = `cat /proc/cpuinfo | grep 'cpu cores' |head -n 1|sed 's/cpu cores\\s*:\\s//'` 30 | return numcores.to_i 31 | end 32 | 33 | def nehalem_or_sandybridge 34 | proc_type = `cat /proc/cpuinfo | grep flags |head -n 1| grep avx` 35 | 36 | if proc_type.chomp.length == 0 37 | return 'Nehalem' 38 | else 39 | return 'Sandy Bridge' 40 | end 41 | end 42 | 43 | def turbo_command_list() 44 | print "turbo : which examines the turbo status \n" 45 | print " probable commands are\n" 46 | print " turbo status : get the current status of turbo\n" 47 | print " turbo enable : enable turbo\n" 48 | print " turbo disable : disable turbo\n" 49 | end 50 | 51 | def multiplier_command_list() 52 | print "multiplier : which allows setting/examining multiplier \n" 53 | print " probable commands are\n" 54 | print " multiplier set : set the multiplier to given number and ONLY in decimals\n" 55 | print " multiplier get : examine the current multiplier\n" 56 | end 57 | 58 | def power_command_list() 59 | print "power : which allows setting/examining TDP / TDC\n" 60 | print " probable commands are\n" 61 | print " power set tdp : set the multiplier to given number and ONLY in decimals\n" 62 | print " power set tdc : set the multiplier to given number and ONLY in decimals\n" 63 | print " power get : examine the current TDP / TDC\n" 64 | end 65 | 66 | def clock_command_list() 67 | print "clock : allows for software clock modulation ( a form of throttling )\n" 68 | print " a good link for understanding this is http://paulsiu.wordpress.com/2007/06/23/does-on-demand-clock-modulation-odcm-conserve-battery/\n" 69 | print " probable commands are\n" 70 | print " clock set : set the number to one of the below or in range between 0-100\n" 71 | print " and i will automatically to the value nearest to\n" 72 | print " 12.5, 25.0, 37.5, 50.0, 63.5, 75, 87.5 (nehalem)\n" 73 | print " sandy bridge supports 6.25% increments\n" 74 | print " but, I (the tool) is not smart yet to distinguish between nehalem and sb\n" 75 | print " so setting to 12.5 increment\n" 76 | print " set to 1 for 12.5%, 2 for 25%, 3 for 37.5%, 4 for 50%, \n" 77 | print" 5 for 63.5%, 6 for 75% and 7 for 87.5%\n" 78 | print " clock status : get clock modulation status\n" 79 | print " clock disable : disable clock modulation\n" 80 | end 81 | 82 | @duty_cycle_array = {0=>"reserved", 1=>'12.5% (default)', 2=>'25%', 3=>'37.5%', 4=>'50%', 5=>'63.5%',6=>'75%',7=>'87.5%'} 83 | 84 | def get_clock_status() 85 | status = `rdmsr 0x19a --bitfield 4:4` 86 | print_command('rdmsr 0x19a --bitfield 4:4') 87 | if status.to_i == 0 88 | print "Clock modulation is disabled\n" 89 | else 90 | print "Clock modulation is enabled\n" 91 | status = `rdmsr 0x19a --bitfield 3:1` 92 | print_command('rdmsr 0x19a --bitfield 3:1') 93 | print "Duty Cycle is #{@duty_cycle_array[status.to_i]}\n" 94 | end 95 | end 96 | 97 | def set_clock_modulation(mult) 98 | if (mult.to_i<0) | (mult.to_i>8) 99 | print "Error: clock set , where should be between 1-7\n" 100 | print " set to 1 for 12.5%, 2 for 25%, 3 for 37.5%, 4 for 50%, \n" 101 | print" 5 for 63.5%, 6 for 75% and 7 for 87.5%\n" 102 | return 103 | end 104 | get_clock_status() 105 | 106 | mult = mult.to_i << 1 107 | mult = mult | 0x10 108 | 109 | for i in (0..12) 110 | status = "wrmsr 0x19a -p#{i} #{mult}" 111 | print_command(status) 112 | system(status) 113 | end 114 | get_clock_status() 115 | end 116 | 117 | def clock_disable() 118 | val = 0x0 119 | for i in (0..(num_cores()*2-1)) 120 | status = "wrmsr 0x19a -p#{i} #{val}" 121 | print_command(status) 122 | system(status) 123 | end 124 | get_clock_status() 125 | end 126 | 127 | def print_command( str ) 128 | print "Running following command in sudo: #{str} \n" 129 | end 130 | 131 | def print_turbo_status() 132 | status = `rdmsr 0x1a0 --bitfield 38:38` 133 | print_command('rdmsr 0x1a0 --bitfield 38:38') 134 | 135 | if status.to_i == 1 136 | print "Turbo is Disabled\n" 137 | else 138 | print "Turbo is Enabled\n" 139 | end 140 | end 141 | 142 | def enable_turbo_status() 143 | status = `rdmsr 0x1a0 --decimal` 144 | print "First checking status\n" 145 | print_command('rdmsr 0x1a0 --decimal') 146 | 147 | status = status.to_i & 0xBFFFFFFFFF #1 the 38th bit 148 | 149 | command = "wrmsr 0x1a0 #{status}" 150 | system(command) 151 | print_command(command) 152 | 153 | status = `rdmsr 0x1a0 --bitfield 38:38` 154 | print "Now checking if the update was successful or not\n" 155 | print_command('rdmsr 0x1a0 --bitfield 38:38') 156 | 157 | if status.to_i == 1 158 | print "Turbo is now Disabled, command failed and i dont know whyq\n" 159 | else 160 | print "Turbo is now Enabled, command succeeded\n" 161 | end 162 | end 163 | 164 | def disable_turbo_status() 165 | status = `rdmsr 0x1a0 --decimal` 166 | status = status.to_i | 0x4000000000 #1 the 38th bit 167 | print "First checking status\n" 168 | print_command('rdmsr 0x1a0 --decimal') 169 | 170 | command = "wrmsr 0x1a0 #{status}" 171 | system(command) 172 | print_command(command) 173 | 174 | status = `rdmsr 0x1a0 --bitfield 38:38` 175 | print "Now checking if the update was successful or not\n" 176 | print_command('rdmsr 0x1a0 --bitfield 38:38') 177 | 178 | if status.to_i == 1 179 | print "Turbo is now Disabled, command succeeded\n" 180 | else 181 | print "Turbo is now Enabled, command failed and i dont know why\n" 182 | end 183 | end 184 | 185 | def get_multiplier() 186 | if nehalem_or_sandybridge == 'Nehalem' 187 | status = `rdmsr 0x198 --decimal` 188 | print_command('rdmsr 0x198 --decimal') 189 | status = status.to_i & 0xFFFF 190 | else 191 | status = `rdmsr 0x198 --decimal --bitfield 15:8` 192 | print_command('rdmsr 0x198 --decimal --bitfield 15:8') 193 | status = status.to_i & 0xFF 194 | end 195 | print " Current Multiplier is #{status}\n" 196 | 197 | status1 = `rdmsr 0xce --decimal --bitfield 47:40` 198 | print_command('rdmsr 0xce --decimal --bitfield 47:40') 199 | print " Minimum Multiplier possible is #{status1.chomp}\n" 200 | 201 | status1 = `rdmsr 0xce --decimal --bitfield 15:8` 202 | print_command('rdmsr 0xce --decimal --bitfield 15:8') 203 | print " Maximum Multiplier in Non-turbo mode is #{status1.chomp}\n" 204 | 205 | turbo1 = `rdmsr 0x1ad --decimal --bitfield 7:0` 206 | print_command('rdmsr 0x1ad --decimal --bitfield 7:0') 207 | turbo2 = `rdmsr 0x1ad --decimal --bitfield 15:8` 208 | print_command('rdmsr 0x1ad --decimal --bitfield 15:8') 209 | turbo3 = `rdmsr 0x1ad --decimal --bitfield 23:16` 210 | print_command('rdmsr 0x1ad --decimal --bitfield 23:16') 211 | turbo4 = `rdmsr 0x1ad --decimal --bitfield 31:24` 212 | print_command('rdmsr 0x1ad --decimal --bitfield 31:24') 213 | turbo5 = `rdmsr 0x1ad --decimal --bitfield 39:32` 214 | print_command('rdmsr 0x1ad --decimal --bitfield 39:32') 215 | turbo6 = `rdmsr 0x1ad --decimal --bitfield 47:40` 216 | print_command('rdmsr 0x1ad --decimal --bitfield 47:40') 217 | 218 | if num_cores()>=5 219 | 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" 220 | elsif (num_cores()<=4 && num_cores()>2) 221 | print " Maximum turbo limit with 1/2/3/4 cores active is #{turbo1.chomp}/#{turbo2.chomp}/#{turbo3.chomp}/#{turbo4.chomp}\n" 222 | else 223 | print " Maximum turbo limit with 1/2 cores active is #{turbo1.chomp}/#{turbo2.chomp}\n" 224 | end 225 | end 226 | 227 | def set_multiplier(mult) 228 | status1 = `rdmsr 0xce --decimal --bitfield 47:40` 229 | minimum_multiplier = status1.chomp.to_i 230 | print_command('rdmsr 0xce --decimal --bitfield 47:40') 231 | 232 | turbo1 = `rdmsr 0x1ad --decimal --bitfield 7:0` 233 | maximum_multiplier = turbo1.chomp.to_i 234 | print_command('rdmsr 0x1ad --decimal --bitfield 7:0') 235 | 236 | if (mult < minimum_multiplier) | (mult > maximum_multiplier) 237 | print "You asked for a multiplier #{mult}\n" 238 | print "The range of input Multiplier is not in range\n" 239 | print "Please put it between #{minimum_multiplier} to #{maximum_multiplier}\n" 240 | 241 | else 242 | 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" 243 | for i in (0..(num_cores()*2-1)) 244 | status = "wrmsr 0x199 -p#{i} #{mult}" 245 | print_command(status) 246 | system(status) 247 | end 248 | end 249 | 250 | get_multiplier() 251 | #print "Current Multiplier is #{status}\n" 252 | end 253 | 254 | def get_power 255 | if nehalem_or_sandybridge != 'Nehalem' 256 | print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" 257 | else 258 | status1 = `rdmsr 0x1ac --bitfield 14:0 --decimal` 259 | print_command('rdmsr 0x1ac --bitfield 14:0 --decimal') 260 | 261 | status2 = `rdmsr 0x1ac --bitfield 30:16 --decimal` 262 | print_command('rdmsr 0x1ac --bitfield 30:16 --decimal') 263 | 264 | print "Current TDP limit is #{status1.to_i * 1/8} watts, TDC limit is #{status2.to_i * 1/8} amps\n" 265 | end 266 | end 267 | 268 | def set_tdp(limit) 269 | if nehalem_or_sandybridge != 'Nehalem' 270 | print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" 271 | else 272 | status1 = `rdmsr 0x1ac --decimal` 273 | print_command('rdmsr 0x1ac --decimal') 274 | 275 | tdp = (status1.to_i & 0xFFFFFFFFFFFF8000) | (0x8000) | (limit.to_i/0.125) #set bits 14:0, as resolution is 1/8 of a watt/amp 276 | 277 | status = "wrmsr 0x1ac #{tdp}" 278 | print_command(status) 279 | system(status) 280 | end 281 | end 282 | 283 | def set_tdc(limit) 284 | if nehalem_or_sandybridge != 'Nehalem' 285 | print "POWER functions DON'T WORK ON SANDY BRIDGE (intel seems to have removed functionality)\n" 286 | else 287 | status1 = `rdmsr 0x1ac --decimal` 288 | print_command('rdmsr 0x1ac --decimal') 289 | 290 | 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 291 | 292 | status = "wrmsr 0x1ac #{tdc}" 293 | print_command(status) 294 | system(status) 295 | end 296 | end 297 | 298 | 299 | #IGNORE THIS FUNCTION - NOT USING IT AT ALL 300 | def disable_ida() 301 | #status = `rdmsr 0x199` 302 | #status = status.to_i(16) 303 | #p status 304 | 305 | #disable_turbo_string = 0x0100 306 | #system("wrmsr 0x199 #{disable_turbo_string}") 307 | 308 | #read the current opportunistic performance status and then write it. so first STATUS and then CTL 309 | curr_status = `rdmsr 0x198 --decimal` 310 | print "current performance status 0x#{curr_status}\n" 311 | curr_status = (curr_status.to_i | 0x100).to_s(16) 312 | print "in order to set ida=disable i will set bit 32 to get the following byte value 0x#{curr_status}\n" 313 | curr_command = "wrmsr 0x199 #{curr_status}" 314 | print "now executing #{curr_command}\n" 315 | system(curr_command) 316 | end 317 | 318 | print "\n\nThis script is totally experimental \n" 319 | print "use it in superuser mode to get access to r/w access \n" 320 | print "also i need msr-tools installed so that rdmsr and wrmsr can work in sudo\n" 321 | print "write quit or ctrl+C to exit\n\n" 322 | print "Now for the blurb on why you might find this script useful:\n" 323 | print "Throttling cpu on battery is one place, some machines including W520\n" 324 | print "have a wierd bios which switches off turbo when machine is booted in\n" 325 | print "battery or some bios implement throttling even when the power is within limit\n" 326 | print "and this tool should allow you to manually set the multiplier\n" 327 | print "Whenever you run a command it will print out what goes in the background\n" 328 | print "like what registers were read/written etc, this should allow one to even\n" 329 | print "write different scripts to automatically run specifics multiplier in battery\n" 330 | print "power and other modes.\n" 331 | print "msr-tools are needed. Furthermore \"modprobe msr\" on command line needs to be executed\n" 332 | print_command_list() 333 | 334 | at_exit{print "exiting, thanks for using\n"} 335 | 336 | while(1) 337 | print ">> " 338 | $input = STDIN.gets.chomp 339 | if $input.downcase.eql? "quit" 340 | break; 341 | end 342 | 343 | if $input.length == 0 344 | print_command_list() 345 | else 346 | commands = $input.split 347 | 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 348 | when "help" 349 | print_command_list() 350 | when "turbo" 351 | if ! commands[1].nil? 352 | case commands[1].downcase 353 | when "status" 354 | print_turbo_status() 355 | when "enable" 356 | enable_turbo_status() 357 | when "disable" 358 | disable_turbo_status() 359 | else 360 | turbo_command_list() 361 | end 362 | else 363 | turbo_command_list() 364 | end 365 | when "multiplier" 366 | if !commands[1].nil? 367 | case commands[1].downcase 368 | when "get" 369 | get_multiplier() 370 | when "set" 371 | if !commands[2].nil? 372 | set_multiplier(commands[2].to_i) 373 | else 374 | multiplier_command_list() 375 | end 376 | else 377 | multiplier_command_list() 378 | end 379 | else 380 | multiplier_command_list() 381 | end 382 | when "power" 383 | if !commands[1].nil? 384 | case commands[1].downcase 385 | when "get" 386 | get_power() 387 | when "set" 388 | if !commands[2].nil? && !commands[3].nil? 389 | case commands[2].downcase 390 | when "tdp" 391 | set_tdp(commands[3]) 392 | when "tdc" 393 | set_tdc(commands[3]) 394 | else 395 | power_command_list() 396 | end 397 | else 398 | power_command_list() 399 | end 400 | else 401 | power_command_list() 402 | end 403 | else 404 | power_command_list() 405 | end 406 | when "clock" 407 | if !commands[1].nil? 408 | case commands[1].downcase 409 | when "status" 410 | get_clock_status() 411 | when "set" 412 | if !commands[2].nil? 413 | set_clock_modulation(commands[2]) 414 | else 415 | clock_command_list() 416 | end 417 | when "disable" 418 | clock_disable() 419 | else 420 | clock_command_list() 421 | end 422 | else 423 | clock_command_list() 424 | end 425 | when "system" 426 | print "number of cores #{num_cores()}\n" 427 | print "trying to distinguish between nehalem/sandy bridge via AVX support... #{nehalem_or_sandybridge}\n" 428 | else 429 | print_command_list() 430 | end 431 | end 432 | 433 | 434 | end 435 | 436 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /src/perfmon-i7z/perfmon-i7z.cpp: -------------------------------------------------------------------------------- 1 | //i7z.c 2 | /* ----------------------------------------------------------------------- * 3 | * 4 | * Copyright 2009 Abhishek Jaiantilal 5 | * 6 | * Under GPL v2 7 | * 8 | * ----------------------------------------------------------------------- */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "perfmon-i7z.h" 27 | //#include "CPUHeirarchy.h" 28 | 29 | #define CPU_FREQUENCY 3291 //this is in mhz 30 | 31 | int Single_Socket(); 32 | int Dual_Socket(); 33 | 34 | int numPhysicalCores, numLogicalCores; 35 | double TRUE_CPU_FREQ; 36 | 37 | #define IA32_THERM_STATUS 0x19C 38 | #define IA32_TEMPERATURE_TARGET 0x1a2 39 | 40 | //Info: I start from index 1 when i talk about cores on CPU 41 | 42 | //Monitoring Version - 1 43 | //4 events at most can be monitored 44 | //put in the value in PERFEVTSEL and the counts are in PMC 45 | #define IA32_PERFEVTSEL0 0x186 46 | #define IA32_PERFEVTSEL1 0x187 47 | #define IA32_PERFEVTSEL2 0x188 48 | #define IA32_PERFEVTSEL3 0x189 49 | #define IA32_PMC0 0x0C1 50 | #define IA32_PMC1 0x0C2 51 | #define IA32_PMC2 0x0C3 52 | #define IA32_PMC3 0x0C4 53 | 54 | //Monitoring Version - 2 55 | //Another 3 events can be then monitored in IA32_FIXED_CTR0 to CTR2 56 | #define IA32_FIXED_CTR_CTL 0x38D 57 | #define IA32_PERF_GLOBAL_CTRL 0x38F 58 | #define IA32_FIXED_CTR0 0x309 //Instruction_Retired.Any 59 | #define IA32_FIXED_CTR1 0x30A //CPU_CLK_Unhalted.Core 60 | #define IA32_FIXED_CTR2 0x30B //CPU_CLK_Unhalted.Ref 61 | 62 | //Performance event number and umask value 63 | #define MEM_INST_RETIRED_LOADS_EVENT 0x0B 64 | #define MEM_INST_RETIRED_LOADS_UMASK 0x01 65 | #define MEM_INST_RETIRED_LOADS 0x010B 66 | 67 | #define MEM_INST_RETIRED_STORES_EVENT 0x0B 68 | #define MEM_INST_RETIRED_STORES_UMASK 0x02 69 | #define MEM_INST_RETIRED_STORES 0x020B 70 | 71 | #define FP_COMP_OPS_EXE_X87_EVENT 0x10 72 | #define FP_COMP_OPS_EXE_X87_UMASK 0x01 73 | #define FP_COMP_OPS_EXE_X87 0x0110 74 | 75 | #define FP_COMP_OPS_EXE_SSE_FP_EVENT 0x10 76 | #define FP_COMP_OPS_EXE_SSE_FP_UMASK 0x04 77 | #define FP_COMP_OPS_EXE_SSE_FP 0x0410 78 | 79 | #define MAX_PROCESSORS_SYSTEM 4 80 | 81 | int error_indx; 82 | 83 | struct therm_status_struct { 84 | int reading_valid; 85 | int resolution_deg_celcius; 86 | int digital_readout; 87 | int power_limit_notification_status; 88 | int power_limit_notification_log; 89 | int thermal_threshold_2_log; 90 | int thermal_threshold_2_status; 91 | int thermal_threshold_1_log; 92 | int thermal_threshold_1_status; 93 | int critical_temperature_log; 94 | int critical_temperature_status; 95 | int PROCHOT_log; 96 | int PROCHOT_event; 97 | int thermal_status_log; 98 | int thermal_status; 99 | 100 | int PROCHOT_temp; //Tj 101 | int current_core_temp; //PROCHOT_temp - digital_readout 102 | }; 103 | 104 | int Get_Bits_Value(unsigned long val, int highbit, int lowbit) 105 | { 106 | unsigned long data = val; 107 | int bits = highbit - lowbit + 1; 108 | if (bits < 64) { 109 | data >>= lowbit; 110 | data &= (1ULL << bits) - 1; 111 | } 112 | return (data); 113 | } 114 | 115 | void Print_Thermal_Status(struct therm_status_struct therm_status) 116 | { 117 | printf("Reading Valid: %d\n", therm_status.reading_valid); 118 | printf("Deg Celcius: %d\n", therm_status.resolution_deg_celcius); 119 | printf("Digital Readout: %d\n", therm_status.digital_readout); 120 | printf("Tj: %d\n", therm_status.PROCHOT_temp); 121 | printf("Current Temp: %d\n", therm_status.current_core_temp); 122 | } 123 | 124 | void Read_Thermal_Status(struct therm_status_struct *therm_status) 125 | { 126 | unsigned long val = 127 | get_msr_value(0, IA32_THERM_STATUS, 63, 0, &error_indx); 128 | therm_status->reading_valid = Get_Bits_Value(val, 32, 31); 129 | therm_status->resolution_deg_celcius = Get_Bits_Value(val, 31, 27); 130 | therm_status->digital_readout = Get_Bits_Value(val, 23, 16); 131 | 132 | val = get_msr_value(0, IA32_TEMPERATURE_TARGET, 63, 0, &error_indx); 133 | therm_status->PROCHOT_temp = Get_Bits_Value(val, 24, 16); 134 | 135 | therm_status->current_core_temp = 136 | therm_status->PROCHOT_temp - therm_status->digital_readout; 137 | } 138 | 139 | unsigned long Read_instruction_retired_any(int cpu) 140 | { 141 | return (get_msr_value(cpu, IA32_FIXED_CTR0, 63, 0, &error_indx)); 142 | } 143 | 144 | unsigned long Read_cpu_clk_unhalted_core(int cpu) 145 | { 146 | return (get_msr_value(cpu, IA32_FIXED_CTR1, 63, 0, &error_indx)); 147 | } 148 | 149 | unsigned long Read_cpu_clk_unhalted_ref(int cpu) 150 | { 151 | return (get_msr_value(cpu, IA32_FIXED_CTR2, 63, 0, &error_indx)); 152 | } 153 | 154 | //////////////PERFORMANCE COUNTER VERSION-1///////////////////////////////////////////////////// 155 | void Set_MV1_Counters(int cpu, int pmc1, int pmc2, int pmc3, int pmc4) 156 | { 157 | int error_indx; 158 | //pmc consists of 1byte of umask and 1byte of event select 159 | //63 = 0110 0011 = enable counter,anythread,os mode and user mode 160 | set_msr_value(cpu, IA32_PERFEVTSEL0, 0x430000 + pmc1, &error_indx); 161 | set_msr_value(cpu, IA32_PERFEVTSEL1, 0x430000 + pmc2, &error_indx); 162 | set_msr_value(cpu, IA32_PERFEVTSEL2, 0x430000 + pmc3, &error_indx); 163 | set_msr_value(cpu, IA32_PERFEVTSEL3, 0x430000 + pmc4, &error_indx); 164 | } 165 | 166 | unsigned long Get_MV1_Counter0(int cpu) 167 | { 168 | return (get_msr_value(cpu, IA32_PMC0, 63, 0, &error_indx)); 169 | } 170 | 171 | unsigned long Get_MV1_Counter1(int cpu) 172 | { 173 | return (get_msr_value(cpu, IA32_PMC1, 63, 0, &error_indx)); 174 | } 175 | 176 | unsigned long Get_MV1_Counter2(int cpu) 177 | { 178 | return (get_msr_value(cpu, IA32_PMC2, 63, 0, &error_indx)); 179 | } 180 | 181 | unsigned long Get_MV1_Counter3(int cpu) 182 | { 183 | return (get_msr_value(cpu, IA32_PMC3, 63, 0, &error_indx)); 184 | } 185 | 186 | void sleep_ms(long long int msecs) 187 | { 188 | struct timespec t_req, t_rem; 189 | int secs_to_sleep = floor((double)msecs / 1000); 190 | int ms_to_sleep = msecs - secs_to_sleep * 1000; 191 | t_req.tv_sec = secs_to_sleep; 192 | t_req.tv_nsec = ms_to_sleep * 1000000; 193 | nanosleep(&t_req, NULL); 194 | } 195 | 196 | long double ctime_long_double() 197 | { 198 | struct timeval current_time; 199 | long double current_time_f; 200 | gettimeofday(¤t_time, NULL); 201 | current_time_f = 202 | (long double)current_time.tv_sec + 203 | (long double)current_time.tv_usec / 1000000; 204 | return (current_time_f); 205 | } 206 | 207 | /////////////////////////////////////////////////////////////////////////////////////////////// 208 | 209 | struct cycle_information { 210 | unsigned long instruction_retired_any; 211 | unsigned long cpu_clk_unhalted_core; 212 | unsigned long cpu_clk_unhalted_ref; 213 | unsigned long mem_inst_retired_stores; 214 | unsigned long mem_inst_retired_loads; 215 | unsigned long fp_comp_ops_exe_sse_fp; 216 | unsigned long fp_comp_ops_exe_x87; 217 | }; 218 | 219 | char *lvalue = NULL; 220 | bool logging = false; 221 | 222 | 223 | void *main_thread(void *filename) 224 | { 225 | int i; 226 | struct cpu_heirarchy_info chi; 227 | struct cpu_socket_info socket_0; 228 | socket_0.max_cpu = 0, socket_0.socket_num = 0; 229 | for(i=0; i<8; i++) 230 | socket_0.processor_num[i] = -1; 231 | 232 | struct cpu_socket_info socket_1; 233 | socket_1.max_cpu = 0, socket_1.socket_num = 0; 234 | for(i=0; i<8; i++) 235 | socket_1.processor_num[i] = -1; 236 | 237 | 238 | int c; 239 | opterr = 0; 240 | 241 | 242 | FILE *fp; 243 | printf("Logging enabled to %s\n", lvalue); 244 | 245 | construct_CPU_Heirarchy_info(&chi); 246 | construct_sibling_list(&chi); 247 | construct_socket_information(&chi, &socket_0, &socket_1); 248 | //print_CPU_Heirarchy(chi); 249 | //print_socket_information(&socket_0); 250 | 251 | 252 | /****************************************** 253 | for(i=0; i<8 ;i++){ 254 | printf("%d %d\n",chi.coreid_num[i],chi.sibling_num[i]); 255 | } 256 | 257 | struct therm_status_struct therm_status; 258 | printf("Number of MSR %d\n", num_msr()); 259 | printf("PMCx width %d\n", bit_width_PMCx()); 260 | 261 | printf("Sizeof long %d\n", sizeof(long)); 262 | printf("value of long %ld\n", 0x7fffffffffffffff); 263 | ******************************************/ 264 | 265 | unsigned long new_value_array[MAX_PROCESSORS_SYSTEM * 4], 266 | old_value_array[MAX_PROCESSORS_SYSTEM * 4]; 267 | 268 | unsigned long instruction_retired_any_old[MAX_PROCESSORS_SYSTEM], 269 | instruction_retired_any_new[MAX_PROCESSORS_SYSTEM]; 270 | unsigned long cpu_clk_unhalted_core_old[MAX_PROCESSORS_SYSTEM], 271 | cpu_clk_unhalted_core_new[MAX_PROCESSORS_SYSTEM]; 272 | unsigned long cpu_clk_unhalted_ref_old[MAX_PROCESSORS_SYSTEM], 273 | cpu_clk_unhalted_ref_new[MAX_PROCESSORS_SYSTEM]; 274 | unsigned long new_tsc[MAX_PROCESSORS_SYSTEM], 275 | old_tsc[MAX_PROCESSORS_SYSTEM]; 276 | 277 | memset(new_value_array, 0, 278 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 279 | memset(old_value_array, 0, 280 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 281 | memset(instruction_retired_any_old, 0, 282 | MAX_PROCESSORS_SYSTEM * sizeof(unsigned long)); 283 | memset(instruction_retired_any_new, 0, 284 | MAX_PROCESSORS_SYSTEM * sizeof(unsigned long)); 285 | memset(cpu_clk_unhalted_core_old, 0, 286 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 287 | memset(cpu_clk_unhalted_core_new, 0, 288 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 289 | memset(cpu_clk_unhalted_ref_old, 0, 290 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 291 | memset(cpu_clk_unhalted_ref_new, 0, 292 | MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 293 | memset(new_tsc, 0, MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 294 | memset(old_tsc, 0, MAX_PROCESSORS_SYSTEM * 4 * sizeof(unsigned long)); 295 | 296 | unsigned long long tsc_overall, instruction_retired_any_overall, 297 | cpu_clk_unhalted_core_overall, cpu_clk_unhalted_ref_overall, 298 | value_array_overall[4]; 299 | 300 | /* new_value = get_msr_value(0,0x186,63,0,&error_indx); 301 | printf("value %ld\n",new_value); 302 | new_value = get_msr_value(0,0x187,63,0,&error_indx); 303 | printf("value %ld\n",new_value); 304 | new_value = get_msr_value(0,0x188,63,0,&error_indx); 305 | printf("value %ld\n",new_value);*/ 306 | 307 | int error_indx; 308 | for (i = 0; i < MAX_PROCESSORS_SYSTEM; i++) { 309 | //below is example of MV-1 for instruction_retired.any 310 | //set_msr_value(0,IA32_PERFEVTSEL0,0x63003c); 311 | Set_MV1_Counters(i, FP_COMP_OPS_EXE_SSE_FP, FP_COMP_OPS_EXE_X87, 312 | MEM_INST_RETIRED_LOADS, 313 | MEM_INST_RETIRED_STORES); 314 | //Needs to set this to enable Monitoring Version - 2 315 | set_msr_value(i, IA32_FIXED_CTR_CTL, 0xFFF, &error_indx); //can be used to stop/start counter 316 | set_msr_value(i, IA32_PERF_GLOBAL_CTRL, 0x70000000FLLU, &error_indx); //this controls both the MV-2 and MV-1 events 317 | //Thus need to enable it always! 318 | } 319 | 320 | bool init_thread = 0; 321 | 322 | printf 323 | ("Core id\t\tCurr Time\tTSC diff \tCurrFREQ (Core/Ref)*CPU_Freq\tInst.Retired\tUnhalted(Core)\tUnhalted(Ref)\tMem.Loads\tMem.Stores\t\tSSE_FP\t\tX87\n"); 324 | 325 | long long int iteration = 0; 326 | int num_online_physical_cores = 0; 327 | long double time_1, time_2, elapsed_time=0; 328 | long double time_3, time_4, time_in_sleep=0; 329 | //struct timeval current_time; 330 | //long double current_time_f; 331 | 332 | while (1) { 333 | time_1 = ctime_long_double(); 334 | if (logging) { 335 | //printf("logging noow"); 336 | fp = fopen(lvalue, "a+"); 337 | //printf("fp=%d", fp); 338 | } 339 | //gettimeofday(¤t_time, NULL); 340 | //current_time_f = (long double)current_time.tv_sec + (long double)current_time.tv_usec/1000000; 341 | //printf("sec %Lf\n", ctime_long_double()); 342 | 343 | tsc_overall = 0, instruction_retired_any_overall = 0, 344 | cpu_clk_unhalted_core_overall = 0, cpu_clk_unhalted_ref_overall = 0; 345 | memset(value_array_overall, 0, sizeof(unsigned long) * 4); 346 | num_online_physical_cores = 0; 347 | 348 | for (i = 0; i < MAX_PROCESSORS_SYSTEM; i++) { 349 | construct_CPU_Heirarchy_info(&chi); 350 | construct_sibling_list(&chi); 351 | construct_socket_information(&chi, &socket_0, &socket_1); 352 | 353 | old_value_array[i * 4 + 0] = new_value_array[i * 4 + 0]; 354 | old_value_array[i * 4 + 1] = new_value_array[i * 4 + 1]; 355 | old_value_array[i * 4 + 2] = new_value_array[i * 4 + 2]; 356 | old_value_array[i * 4 + 3] = new_value_array[i * 4 + 3]; 357 | 358 | old_tsc[i] = new_tsc[i]; 359 | instruction_retired_any_old[i] = instruction_retired_any_new[i]; 360 | cpu_clk_unhalted_core_old[i] = cpu_clk_unhalted_core_new[i]; 361 | cpu_clk_unhalted_ref_old[i] = cpu_clk_unhalted_ref_new[i]; 362 | 363 | new_tsc[i] = rdtsc(); 364 | //new_value = get_msr_value(0,IA32_PMC0,63,0,&error_indx); 365 | new_value_array[i * 4 + 0] = Get_MV1_Counter0(i); 366 | new_value_array[i * 4 + 1] = Get_MV1_Counter1(i); 367 | new_value_array[i * 4 + 2] = Get_MV1_Counter2(i); 368 | new_value_array[i * 4 + 3] = Get_MV1_Counter3(i); 369 | 370 | instruction_retired_any_new[i] = Read_instruction_retired_any(i); 371 | cpu_clk_unhalted_core_new[i] = Read_cpu_clk_unhalted_core(i); 372 | cpu_clk_unhalted_ref_new[i] = Read_cpu_clk_unhalted_ref(i); 373 | 374 | if ((iteration > 0) 375 | && (socket_0.processor_num[i] != -1)) { 376 | num_online_physical_cores++; 377 | if (iteration % 10 == 0) {printf("%10d\t%12.2Lf\t", socket_0.processor_num[i], ctime_long_double());} 378 | if (logging) {fprintf(fp, "%10d\t%12.2Lf\t", socket_0.processor_num[i], ctime_long_double());} 379 | 380 | if (iteration % 10 == 0) 381 | printf("%10llu\t%10f\t\t", (new_tsc[i] - old_tsc[i]), 382 | CPU_FREQUENCY * ((double) (cpu_clk_unhalted_core_new[i] - cpu_clk_unhalted_core_old[i])) / ((double) (cpu_clk_unhalted_ref_new[i] - cpu_clk_unhalted_ref_old[i]))); 383 | if (logging) { 384 | fprintf(fp, "%10llu\t%10f\t\t", (new_tsc[i] - old_tsc[i]), 385 | CPU_FREQUENCY * ((double) (cpu_clk_unhalted_core_new[i] - cpu_clk_unhalted_core_old[i])) / ((double)(cpu_clk_unhalted_ref_new[i] - cpu_clk_unhalted_ref_old[i]))); 386 | } 387 | tsc_overall += (new_tsc[i] - old_tsc[i]); 388 | 389 | if (iteration % 10 == 0) {printf("%10lu\t", instruction_retired_any_new[i] - instruction_retired_any_old[i]);} 390 | if (logging) {fprintf(fp, "%10lu\t", instruction_retired_any_new[i] - instruction_retired_any_old[i]);} 391 | instruction_retired_any_overall += (instruction_retired_any_new[i] - instruction_retired_any_old[i]); 392 | 393 | if (iteration % 10 == 0) {printf("%10lu\t", cpu_clk_unhalted_core_new[i] - cpu_clk_unhalted_core_old[i]);} 394 | if (logging) {fprintf(fp, "%10lu\t", cpu_clk_unhalted_core_new[i] - cpu_clk_unhalted_core_old[i]);} 395 | cpu_clk_unhalted_core_overall += (cpu_clk_unhalted_core_new[i] - cpu_clk_unhalted_core_old[i]); 396 | 397 | if (iteration % 10 == 0) {printf("%10lu\t", cpu_clk_unhalted_ref_new[i] - cpu_clk_unhalted_ref_old[i]);} 398 | if (logging) {fprintf(fp, "%10lu\t", cpu_clk_unhalted_ref_new[i] - cpu_clk_unhalted_ref_old[i]);} 399 | cpu_clk_unhalted_ref_overall += (cpu_clk_unhalted_ref_new[i] - cpu_clk_unhalted_ref_old[i]); 400 | 401 | if (iteration % 10 == 0) {printf("%10lu\t", new_value_array[i * 4 + 0] - old_value_array[i * 4 + 0]);} 402 | if (logging) {fprintf(fp, "%10lu\t", new_value_array[i * 4 + 0] - old_value_array[i * 4 + 0]);} 403 | value_array_overall[0] += (new_value_array[i * 4 + 0] - old_value_array[i * 4 + 0]); 404 | 405 | if (iteration % 10 == 0) {printf("%10lu\t", new_value_array[i * 4 + 1] - old_value_array[i * 4 + 1]);} 406 | if (logging) {fprintf(fp, "%10lu\t", new_value_array[i * 4 + 1] - old_value_array[i * 4 + 1]);} 407 | value_array_overall[1] += (new_value_array[i * 4 + 1] - old_value_array[i * 4 + 1]); 408 | 409 | if (iteration % 10 == 0) {printf("%10lu\t", new_value_array[i * 4 + 2] - old_value_array[i * 4 + 2]);} 410 | if (logging) {fprintf(fp, "%10lu\t", new_value_array[i * 4 + 2] - old_value_array[i * 4 + 2]);} 411 | value_array_overall[2] += (new_value_array[i * 4 + 2] - old_value_array[i * 4 + 2]); 412 | 413 | if (iteration % 10 == 0) {printf("%10lu\n", new_value_array[i * 4 + 3] - old_value_array[i * 4 + 3]);} 414 | if (logging) {fprintf(fp, "%10lu\n", new_value_array[i * 4 + 3] - old_value_array[i * 4 + 3]);} 415 | value_array_overall[3] += (new_value_array[i * 4 + 3] - old_value_array[i * 4 + 3]); 416 | } 417 | //Read_Thermal_Status(&therm_status); 418 | //Print_Thermal_Status(therm_status); 419 | } 420 | 421 | if ((iteration > 0) && (iteration % 10 == 0)) { 422 | printf("Overall (%d/%d)\t%12.2Lf\t", 423 | num_online_physical_cores, 4, 424 | ctime_long_double()); 425 | printf("%10llu\t%10f\t\t", tsc_overall, 426 | CPU_FREQUENCY * ((double)cpu_clk_unhalted_core_overall / 427 | (double)cpu_clk_unhalted_ref_overall)); 428 | printf("%10llu\t", instruction_retired_any_overall); 429 | printf("%10llu\t", cpu_clk_unhalted_core_overall); 430 | printf("%10llu\t", cpu_clk_unhalted_ref_overall); 431 | printf("%10llu\t", value_array_overall[0]); 432 | printf("%10llu\t", value_array_overall[1]); 433 | printf("%10llu\t", value_array_overall[2]); 434 | printf("%10llu\t", value_array_overall[3]); 435 | printf("\n"); 436 | 437 | printf 438 | ("--------------------------------------------------------------------------------------------"); 439 | printf 440 | ("--------------------------------------------------------------------------------------------\n"); 441 | } 442 | if ((logging) && (iteration > 0)) { 443 | fprintf(fp, "Overall (%d/%d)\t%12.2Lf\t", 444 | num_online_physical_cores, 4, 445 | ctime_long_double()); 446 | fprintf(fp, "%10llu\t%10f\t", tsc_overall, 447 | CPU_FREQUENCY * ((double)cpu_clk_unhalted_core_overall / 448 | (double)cpu_clk_unhalted_ref_overall)); 449 | fprintf(fp, "%10llu\t", 450 | instruction_retired_any_overall); 451 | fprintf(fp, "%10llu\t", cpu_clk_unhalted_core_overall); 452 | fprintf(fp, "%10llu\t", cpu_clk_unhalted_ref_overall); 453 | fprintf(fp, "%10llu\t", value_array_overall[0]); 454 | fprintf(fp, "%10llu\t", value_array_overall[1]); 455 | fprintf(fp, "%10llu\t", value_array_overall[2]); 456 | fprintf(fp, "%10llu\t", value_array_overall[3]); 457 | fprintf(fp, "\n"); 458 | } 459 | //fflush(fp); 460 | fflush(stdout); 461 | 462 | iteration++; 463 | if (logging) { 464 | fclose(fp); 465 | } 466 | time_2 = ctime_long_double(); 467 | 468 | elapsed_time += (time_2 - time_1); 469 | if (iteration % 10 == 0) { 470 | printf("Avg elapsed time %Lf\n", elapsed_time/iteration); 471 | } 472 | 473 | time_3 = ctime_long_double(); 474 | //sleep(1); 475 | sleep_ms(800); 476 | time_4 = ctime_long_double(); 477 | time_in_sleep += (time_4 - time_3); 478 | if (iteration % 10 == 0) { 479 | printf("Avg Sleep time %Lf\n", time_in_sleep/iteration); 480 | } 481 | // 482 | } 483 | 484 | } 485 | 486 | void print_scheduler(void) 487 | { 488 | int schedType; 489 | 490 | schedType = sched_getscheduler(getpid()); 491 | 492 | switch(schedType) 493 | { 494 | case SCHED_FIFO: 495 | printf("Pthread Policy is SCHED_FIFO\n"); 496 | break; 497 | case SCHED_OTHER: 498 | printf("Pthread Policy is SCHED_OTHER\n"); 499 | break; 500 | case SCHED_RR: 501 | printf("Pthread Policy is SCHED_OTHER\n"); 502 | break; 503 | default: 504 | printf("Pthread Policy is UNKNOWN\n"); 505 | } 506 | } 507 | 508 | 509 | int main(int argc, char **argv) 510 | { 511 | //sam siewert rocks! http://avatar.colorado.edu/resource/linux_examples/pthread.c 512 | pthread_attr_t rt_sched_attr; 513 | int rt_max_prio, rt_min_prio, rc; 514 | struct sched_param rt_param, nrt_param; 515 | 516 | print_scheduler(); 517 | 518 | pthread_attr_init(&rt_sched_attr); 519 | pthread_attr_setinheritsched(&rt_sched_attr, PTHREAD_EXPLICIT_SCHED); 520 | pthread_attr_setschedpolicy(&rt_sched_attr, SCHED_RR); 521 | 522 | rt_max_prio = sched_get_priority_max(SCHED_FIFO); 523 | rt_min_prio = sched_get_priority_min(SCHED_FIFO); 524 | 525 | rc=sched_getparam(getpid(), &nrt_param); 526 | rt_param.sched_priority = rt_max_prio; 527 | rc=sched_setscheduler(getpid(), SCHED_FIFO, &rt_param); 528 | 529 | if (rc) {printf("ERROR; sched_setscheduler rc is %d\n", rc); perror(NULL); exit(-1);} 530 | print_scheduler(); 531 | 532 | int c; 533 | while ((c = getopt(argc, argv, "l:")) != -1) { 534 | switch (c) { 535 | case 'l': 536 | logging = true; 537 | lvalue = optarg; 538 | break; 539 | case '?': 540 | if (optopt == 'l') 541 | fprintf(stderr, 542 | "Option -%c requires an argument\n", 543 | optopt); 544 | default: 545 | abort(); 546 | } 547 | } 548 | 549 | pthread_t mainthread; 550 | int iret; 551 | 552 | iret = pthread_create(&mainthread, NULL, main_thread, NULL); 553 | 554 | pthread_join(mainthread, NULL); 555 | return (1); 556 | } 557 | -------------------------------------------------------------------------------- /src/helper_functions.c: -------------------------------------------------------------------------------- 1 | /* This file is modified from source available at http://www.kernel.org/pub/linux/utils/cpu/msr-tools/ 2 | for Model specific cpu registers 3 | Modified to take i7 into account by Abhishek Jaiantilal abhishek.jaiantilal@colorado.edu 4 | 5 | // Information about i7's MSR in 6 | // http://download.intel.com/design/processor/applnots/320354.pdf 7 | // Appendix B of http://www.intel.com/Assets/PDF/manual/253669.pdf 8 | 9 | //about rdmsr 10 | #ident "$Id: rdmsr.c,v 1.4 2004/07/20 15:54:59 hpa Exp $" 11 | ----------------------------------------------------------------------- * 12 | * 13 | * Copyright 2000 Transmeta Corporation - All Rights Reserved 14 | * 15 | * This program is free software; you can redistribute it and/or modify 16 | * it under the terms of the GNU General Public License as published by 17 | * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA; 19 | * either version 2 of the License, or (at your option) any later 20 | * version; incorporated herein by reference. 21 | * 22 | * ----------------------------------------------------------------------- */ 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "i7z.h" 39 | #include "intel.h" 40 | 41 | extern struct program_options prog_options; 42 | bool E7_mp_present=false; 43 | 44 | // Read temperature 45 | #define IA32_THERM_STATUS 0x19C 46 | #define IA32_TEMPERATURE_TARGET 0x1a2 47 | #define IA32_PACKAGE_THERM_STATUS 0x1b1 48 | 49 | int Get_Bits_Value(unsigned long val,int highbit, int lowbit){ 50 | unsigned long data = val; 51 | int bits = highbit - lowbit + 1; 52 | if(bits<64){ 53 | data >>= lowbit; 54 | data &= (1ULL<stepping); 88 | printf ("i7z DEBUG: Model %x\n", proc_info->model); 89 | printf ("i7z DEBUG: Family %x\n", proc_info->family); 90 | printf ("i7z DEBUG: Processor Type %x\n", proc_info->processor_type); 91 | // printf(" Extended Family %x\n", (short int*)(&proc_info->extended_family)); 92 | // printf(" Extended Family %d\n", proc_info->extended_family); 93 | } 94 | 95 | void init_ncurses() 96 | { 97 | initscr(); 98 | cbreak(); 99 | noecho(); 100 | nodelay(stdscr, TRUE); 101 | start_color(); /* initialize colors */ 102 | use_default_colors (); 103 | init_pair (1, COLOR_GREEN, -1); 104 | init_pair (2, COLOR_YELLOW, -1); 105 | init_pair (3, COLOR_RED, -1); 106 | init_pair (4, COLOR_WHITE, -1); 107 | } 108 | 109 | static inline void get_vendor (char *vendor_string) 110 | { 111 | //get vendor name 112 | unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; 113 | __get_cpuid (eax, &eax, &ebx, &ecx, &edx); 114 | memcpy (vendor_string, &ebx, 4); 115 | memcpy (vendor_string + 4, &edx, 4); 116 | memcpy (vendor_string + 8, &ecx, 4); 117 | vendor_string[12] = '\0'; 118 | // printf("Vendor %s\n",vendor_string); 119 | } 120 | 121 | int turbo_status () 122 | { 123 | //turbo state flag 124 | unsigned int eax = 6, ebx, ecx, edx; 125 | __get_cpuid (eax, &eax, &ebx, &ecx, &edx); 126 | return ((eax & 0x2) >> 1); 127 | } 128 | 129 | static inline void get_familyinformation (struct family_info *proc_info) 130 | { 131 | //get info about CPU 132 | unsigned int eax = 1, ebx, ecx, edx; 133 | __get_cpuid (eax, &eax, &ebx, &ecx, &edx); 134 | // printf ("eax %x\n", b); 135 | proc_info->stepping = eax & 0x0000000F; //bits 3:0 136 | // tack extended model id onto model number 137 | proc_info->model = ((eax & 0x000F0000) >> 12) + ((eax & 0x000000F0) >> 4); //bits 7:4 and 19:16 138 | proc_info->family = (eax & 0x00000F00) >> 8; //bits 11:8 139 | proc_info->processor_type = (eax & 0x00007000) >> 12; //bits 13:12 140 | //proc_info->extended_model = (eax & 0x000F0000) >> 16; //bits 19:16 141 | proc_info->extended_family = (eax & 0x0FF00000) >> 20; //bits 27:20 142 | } 143 | 144 | double estimate_MHz () 145 | { 146 | //copied blantantly from http://www.cs.helsinki.fi/linux/linux-kernel/2001-37/0256.html 147 | /* 148 | * $Id: MHz.c,v 1.4 2001/05/21 18:58:01 davej Exp $ 149 | * This file is part of x86info. 150 | * (C) 2001 Dave Jones. 151 | * 152 | * Licensed under the terms of the GNU GPL License version 2. 153 | * 154 | * Estimate CPU MHz routine by Andrea Arcangeli 155 | * Small changes by David Sterba 156 | * 157 | */ 158 | struct timezone tz; 159 | struct timeval tvstart, tvstop; 160 | unsigned long long int cycles[2]; /* must be 64 bit */ 161 | unsigned long long int microseconds; /* total time taken */ 162 | 163 | memset (&tz, 0, sizeof (tz)); 164 | 165 | /* get this function in cached memory */ 166 | gettimeofday (&tvstart, &tz); 167 | cycles[0] = rdtsc (); 168 | gettimeofday (&tvstart, &tz); 169 | 170 | /* we don't trust that this is any specific length of time */ 171 | /*1 sec will cause rdtsc to overlap multiple times perhaps. 100msecs is a good spot */ 172 | usleep (10000); 173 | 174 | cycles[1] = rdtsc (); 175 | gettimeofday (&tvstop, &tz); 176 | microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) + 177 | (tvstop.tv_usec - tvstart.tv_usec); 178 | 179 | unsigned long long int elapsed = 0; 180 | if (cycles[1] < cycles[0]) 181 | { 182 | //printf("c0 = %llu c1 = %llu",cycles[0],cycles[1]); 183 | elapsed = UINT32_MAX - cycles[0]; 184 | elapsed = elapsed + cycles[1]; 185 | //printf("c0 = %llu c1 = %llu max = %llu elapsed=%llu\n",cycles[0], cycles[1], UINT32_MAX,elapsed); 186 | } 187 | else 188 | { 189 | elapsed = cycles[1] - cycles[0]; 190 | //printf("\nc0 = %llu c1 = %llu elapsed=%llu\n",cycles[0], cycles[1],elapsed); 191 | } 192 | 193 | double mhz = elapsed / microseconds; 194 | 195 | 196 | //printf("%llg MHz processor (estimate). diff cycles=%llu microseconds=%llu \n", mhz, elapsed, microseconds); 197 | //printf("%g elapsed %llu microseconds %llu\n",mhz, elapsed, microseconds); 198 | return (mhz); 199 | } 200 | 201 | uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, 202 | unsigned int lowbit, int* error_indx) 203 | { 204 | uint64_t data; 205 | int fd; 206 | // char *pat; 207 | // int width; 208 | char msr_file_name[64]; 209 | int bits; 210 | *error_indx =0; 211 | 212 | sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); 213 | fd = open (msr_file_name, O_RDONLY); 214 | if (fd < 0) 215 | { 216 | if (errno == ENXIO) 217 | { 218 | //fprintf (stderr, "rdmsr: No CPU %d\n", cpu); 219 | *error_indx = 1; 220 | return 1; 221 | } else if (errno == EIO) { 222 | //fprintf (stderr, "rdmsr: CPU %d doesn't support MSRs\n", cpu); 223 | *error_indx = 1; 224 | return 1; 225 | } else { 226 | //perror ("rdmsr:open"); 227 | *error_indx = 1; 228 | return 1; 229 | //exit (127); 230 | } 231 | } 232 | 233 | if (pread (fd, &data, sizeof data, reg) != sizeof data) 234 | { 235 | perror ("rdmsr:pread"); 236 | exit (127); 237 | } 238 | 239 | close (fd); 240 | 241 | bits = highbit - lowbit + 1; 242 | if (bits < 64) 243 | { 244 | /* Show only part of register */ 245 | data >>= lowbit; 246 | data &= (1ULL << bits) - 1; 247 | } 248 | 249 | /* Make sure we get sign correct */ 250 | if (data & (1ULL << (bits - 1))) 251 | { 252 | data &= ~(1ULL << (bits - 1)); 253 | data = -data; 254 | } 255 | 256 | *error_indx = 0; 257 | return (data); 258 | } 259 | 260 | uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data) 261 | { 262 | int fd; 263 | char msr_file_name[64]; 264 | 265 | sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); 266 | fd = open (msr_file_name, O_WRONLY); 267 | if (fd < 0) 268 | { 269 | if (errno == ENXIO) 270 | { 271 | fprintf (stderr, "wrmsr: No CPU %d\n", cpu); 272 | exit (2); 273 | } else if (errno == EIO) { 274 | fprintf (stderr, "wrmsr: CPU %d doesn't support MSRs\n", cpu); 275 | exit (3); 276 | } else { 277 | perror ("wrmsr:open"); 278 | exit (127); 279 | } 280 | } 281 | 282 | if (pwrite (fd, &data, sizeof data, reg) != sizeof data) 283 | { 284 | perror ("wrmsr:pwrite"); 285 | exit (127); 286 | } 287 | close(fd); 288 | return(1); 289 | } 290 | 291 | 292 | //Below code 293 | /* ----------------------------------------------------------------------- * 294 | * 295 | * Copyright 2010 Abhishek Jaiantilal 296 | * 297 | * Under GPL v2 298 | * 299 | * ----------------------------------------------------------------------- */ 300 | 301 | 302 | // sets processor version 303 | void Print_Information_Processor(bool* nehalem, bool* sandy_bridge, bool* haswell) 304 | { 305 | struct family_info proc_info; 306 | 307 | char vendor_string[13]; 308 | get_vendor (vendor_string); 309 | 310 | if (strcmp (vendor_string, "GenuineIntel") == 0) { 311 | printf ("i7z DEBUG: Found Intel Processor\n"); 312 | } else { 313 | printf ("Intel processor was not detected in CPUID\n"); 314 | exit (1); 315 | } 316 | 317 | get_familyinformation (&proc_info); 318 | print_family_info (&proc_info); 319 | 320 | debug(prog_options.quiet, "msr = Model Specific Register"); 321 | if (proc_info.family >= 0x6) { 322 | printf("%d", proc_info.model); 323 | switch (get_intel_model(proc_info.model)) { 324 | case INTEL_NEHALEM: 325 | case INTEL_WESTMERE: 326 | *nehalem = true; 327 | break; 328 | case INTEL_SANDYBRIDGE: 329 | case INTEL_IVYBRIDGE: 330 | *sandy_bridge = true; 331 | break; 332 | case INTEL_HASWELL: 333 | case INTEL_BROADWELL: 334 | case INTEL_KABYLAKE: 335 | case INTEL_CANNONLAKE: 336 | *haswell = true; 337 | break; 338 | default: 339 | break; 340 | } 341 | } else { 342 | error("Unknown, possibly pre i7 processor detected."); 343 | exit (1); 344 | } 345 | } 346 | 347 | void Test_Or_Make_MSR_DEVICE_FILES() 348 | { 349 | //test if the msr file exists 350 | if (access ("/dev/cpu/0/msr", F_OK) == 0) 351 | { 352 | printf ("i7z DEBUG: msr device files exist /dev/cpu/*/msr\n"); 353 | if (access ("/dev/cpu/0/msr", W_OK) == 0) 354 | { 355 | //a system mght have been set with msr allowable to be written 356 | //by a normal user so... 357 | //Do nothing. 358 | printf ("i7z DEBUG: You have write permissions to msr device files\n"); 359 | } else { 360 | printf ("i7z DEBUG: You DO NOT have write permissions to msr device files\n"); 361 | printf ("i7z DEBUG: A solution is to run this program as root\n"); 362 | exit (1); 363 | } 364 | } else { 365 | printf ("i7z DEBUG: msr device files DO NOT exist, trying out a makedev script\n"); 366 | if (geteuid () == 0) 367 | { 368 | //Try the Makedev script 369 | //sourced from MAKEDEV-cpuid-msr script in msr-tools 370 | system ("msr_major=202; \ 371 | cpuid_major=203; \ 372 | n=0; \ 373 | while [ $n -lt 16 ]; do \ 374 | mkdir -m 0755 -p /dev/cpu/$n; \ 375 | mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n; \ 376 | mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n; \ 377 | n=`expr $n + 1`; \ 378 | done; \ 379 | "); 380 | printf ("i7z DEBUG: modprobbing for msr\n"); 381 | system ("modprobe msr"); 382 | } else { 383 | printf ("i7z DEBUG: You DO NOT have root privileges, mknod to create device entries won't work out\n"); 384 | printf ("i7z DEBUG: A solution is to run this program as root\n"); 385 | exit (1); 386 | } 387 | } 388 | } 389 | double cpufreq_info() 390 | { 391 | //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present 392 | //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID 393 | //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ 394 | system 395 | ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); 396 | 397 | 398 | //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo 399 | FILE *tmp_file; 400 | tmp_file = fopen ("/tmp/cpufreq.txt", "r"); 401 | char tmp_str[30]; 402 | fgets (tmp_str, 30, tmp_file); 403 | fclose (tmp_file); 404 | return atof(tmp_str); 405 | } 406 | 407 | int check_and_return_processor(char*strinfo) 408 | { 409 | char *t1; 410 | if (strstr(strinfo,"processor") !=NULL) { 411 | strtok(strinfo,":"); 412 | t1 = strtok(NULL, " "); 413 | return(atoi(t1)); 414 | } else { 415 | return(-1); 416 | } 417 | } 418 | 419 | int check_and_return_physical_id(char*strinfo) 420 | { 421 | char *t1; 422 | if (strstr(strinfo,"physical id") !=NULL) { 423 | strtok(strinfo,":"); 424 | t1 = strtok(NULL, " "); 425 | return(atoi(t1)); 426 | } else { 427 | return(-1); 428 | } 429 | } 430 | 431 | int check_and_return_core_id(char*strinfo) 432 | { 433 | char *t1; 434 | if (strstr(strinfo,"core id") !=NULL) { 435 | strtok(strinfo,":"); 436 | t1 = strtok(NULL, " "); 437 | return(atoi(t1)); 438 | } else { 439 | return(-1); 440 | } 441 | } 442 | 443 | void construct_sibling_list(struct cpu_hierarchy_info* chi) 444 | { 445 | int i,j,core_id,socket_id; 446 | for (i=0;i< chi->max_online_cpu ;i++) { 447 | assert(i < MAX_HI_PROCESSORS); 448 | chi->sibling_num[i]=-1; 449 | } 450 | 451 | chi->HT=false; 452 | for (i=0;i< chi->max_online_cpu ;i++) { 453 | assert(i < MAX_HI_PROCESSORS); 454 | core_id = chi->coreid_num[i]; 455 | socket_id = chi->package_num[i]; 456 | for (j=i+1;j< chi->max_online_cpu ;j++) { 457 | assert(j < MAX_HI_PROCESSORS); 458 | if (chi->coreid_num[j] == core_id && chi->package_num[j] == socket_id) { 459 | chi->sibling_num[j] = i; 460 | chi->sibling_num[i] = j; 461 | chi->display_cores[i] = 1; 462 | chi->display_cores[j] = -1; 463 | chi->HT=true; 464 | continue; 465 | } 466 | } 467 | } 468 | //for cores that donot have a sibling put in 1 469 | for (i=0;i< chi->max_online_cpu ;i++) { 470 | assert(i < MAX_HI_PROCESSORS); 471 | if (chi->sibling_num[i] ==-1) 472 | chi->display_cores[i] = 1; 473 | } 474 | } 475 | 476 | void construct_socket_information(struct cpu_hierarchy_info* chi, 477 | struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1, 478 | int socket_0_num, int socket_1_num) 479 | { 480 | int i; 481 | 482 | socket_0->max_cpu=0; 483 | socket_0->num_physical_cores=0; 484 | socket_0->num_logical_cores=0; 485 | socket_1->max_cpu=0; 486 | socket_1->num_physical_cores=0; 487 | socket_1->num_logical_cores=0; 488 | 489 | 490 | for (i=0;i< chi->max_online_cpu ;i++) { 491 | assert(i < MAX_HI_PROCESSORS); 492 | if (chi->display_cores[i]!=-1) { 493 | if (chi->package_num[i]==socket_0_num) { 494 | assert(socket_0->max_cpu < MAX_SK_PROCESSORS); 495 | socket_0->processor_num[socket_0->max_cpu]=chi->processor_num[i]; 496 | socket_0->max_cpu++; 497 | socket_0->num_physical_cores++; 498 | socket_0->num_logical_cores++; 499 | } 500 | if (chi->package_num[i]==socket_1_num) { 501 | assert(socket_1->max_cpu < MAX_SK_PROCESSORS); 502 | socket_1->processor_num[socket_1->max_cpu]=chi->processor_num[i]; 503 | socket_1->max_cpu++; 504 | socket_1->num_physical_cores++; 505 | socket_1->num_logical_cores++; 506 | } 507 | } else { 508 | if (chi->package_num[i]==socket_0_num) { 509 | socket_0->num_logical_cores++; 510 | } 511 | if (chi->package_num[i]==socket_1_num) { 512 | socket_1->num_logical_cores++; 513 | } 514 | } 515 | } 516 | } 517 | 518 | void print_socket_information(struct cpu_socket_info* socket) 519 | { 520 | int i; 521 | char socket_list[200]=""; 522 | 523 | for (i=0;i< socket->max_cpu ;i++) { 524 | assert(i < MAX_SK_PROCESSORS); 525 | if (socket->processor_num[i]!=-1) { 526 | sprintf(socket_list,"%s%d,",socket_list,socket->processor_num[i]); 527 | } 528 | } 529 | 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); 530 | } 531 | 532 | void construct_CPU_Hierarchy_info(struct cpu_hierarchy_info* chi) 533 | { 534 | FILE *fp = fopen("/proc/cpuinfo","r"); 535 | char strinfo[200]; 536 | 537 | int processor_num, physicalid_num, coreid_num; 538 | int it_processor_num=-1, it_physicalid_num=-1, it_coreid_num=-1; 539 | int tmp_processor_num, tmp_physicalid_num, tmp_coreid_num; 540 | int old_processor_num=-1; 541 | 542 | memset(chi, 0, sizeof(*chi)); 543 | 544 | if (fp!=NULL) { 545 | while ( fgets(strinfo,200,fp) != NULL) { 546 | // printf(strinfo); 547 | tmp_processor_num = check_and_return_processor(strinfo); 548 | tmp_physicalid_num = check_and_return_physical_id(strinfo); 549 | tmp_coreid_num = check_and_return_core_id(strinfo); 550 | 551 | 552 | if (tmp_processor_num != -1) { 553 | it_processor_num++; 554 | processor_num = tmp_processor_num; 555 | assert(it_processor_num < MAX_HI_PROCESSORS); 556 | chi->processor_num[it_processor_num] = processor_num; 557 | } 558 | if (tmp_physicalid_num != -1) { 559 | it_physicalid_num++; 560 | physicalid_num = tmp_physicalid_num; 561 | assert(it_physicalid_num < MAX_HI_PROCESSORS); 562 | chi->package_num[it_physicalid_num] = physicalid_num; 563 | } 564 | if (tmp_coreid_num != -1) { 565 | it_coreid_num++; 566 | coreid_num = tmp_coreid_num; 567 | assert(it_coreid_num < MAX_HI_PROCESSORS); 568 | chi->coreid_num[it_coreid_num] = coreid_num; 569 | } 570 | if (processor_num != old_processor_num) { 571 | old_processor_num = processor_num; 572 | } 573 | } 574 | } 575 | chi->max_online_cpu = it_processor_num+1; 576 | fclose(fp); 577 | } 578 | 579 | void print_CPU_Hierarchy(struct cpu_hierarchy_info chi) 580 | { 581 | int i; 582 | printf("\n------------------------------\n--[core id]--- Other information\n-------------------------------------\n"); 583 | for (i=0;i < chi.max_online_cpu;i++) { 584 | assert(i < MAX_HI_PROCESSORS); 585 | printf("--[%d] Processor number %d\n",i,chi.processor_num[i]); 586 | printf("--[%d] Socket number/Hyperthreaded Sibling number %d,%d\n",i,chi.package_num[i],chi.sibling_num[i]); 587 | printf("--[%d] Core id number %d\n",i,chi.coreid_num[i]); 588 | printf("--[%d] Display core in i7z Tool: %s\n\n",i,(chi.display_cores[i]==1)?"Yes":"No"); 589 | } 590 | } 591 | 592 | int in_core_list(int ii,int* core_list) 593 | { 594 | int i; 595 | int in=0; 596 | for (i=0;i<8;i++) { 597 | if (ii == core_list[i]) { 598 | in=1; 599 | break; 600 | } 601 | } 602 | return(in); 603 | } 604 | 605 | bool file_exists(char* filename) 606 | { 607 | if (access(filename, F_OK) == 0) 608 | { 609 | return true; 610 | } else { 611 | return false; 612 | } 613 | } 614 | -------------------------------------------------------------------------------- /src/perfmon-i7z/helper_functions.cpp: -------------------------------------------------------------------------------- 1 | /* This file is modified from source available at http://www.kernel.org/pub/linux/utils/cpu/msr-tools/ 2 | for Model specific cpu registers 3 | Modified to take i7 into account by Abhishek Jaiantilal abhishek.jaiantilal@colorado.edu 4 | 5 | // Information about i7's MSR in 6 | // http://download.intel.com/design/processor/applnots/320354.pdf 7 | // Appendix B of http://www.intel.com/Assets/PDF/manual/253669.pdf 8 | 9 | 10 | #ident "$Id: rdmsr.c,v 1.4 2004/07/20 15:54:59 hpa Exp $" 11 | ----------------------------------------------------------------------- * 12 | * 13 | * Copyright 2000 Transmeta Corporation - All Rights Reserved 14 | * 15 | * This program is free software; you can redistribute it and/or modify 16 | * it under the terms of the GNU General Public License as published by 17 | * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, 18 | * USA; either version 2 of the License, or (at your option) any later 19 | * version; incorporated herein by reference. 20 | * 21 | * ----------------------------------------------------------------------- */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "perfmon-i7z.h" 35 | 36 | #define UINT32_MAX (0xffffffff) 37 | 38 | //#define ULLONG_MAX 18446744073709551615 39 | 40 | /////////////////////////////////////////READ TEMPERATURE//////////////////////////////////////////// 41 | #define IA32_THERM_STATUS 0x19C 42 | #define IA32_TEMPERATURE_TARGET 0x1a2 43 | 44 | 45 | 46 | /*int Get_Bits_Value(unsigned long val,int highbit, int lowbit){ 47 | unsigned long data = val; 48 | int bits = highbit - lowbit + 1; 49 | if(bits<64){ 50 | data >>= lowbit; 51 | data &= (1ULL<> 8 ); 81 | } 82 | 83 | int bit_width_PMCx() 84 | { 85 | unsigned int b; 86 | asm volatile ("mov %1, %%eax;" 87 | "cpuid;" 88 | "mov %%eax, %0;" 89 | :"=r" (b) 90 | :"r" (0x0a) 91 | :"%eax" 92 | ); 93 | return( (b & 0xFF0000) >> 16 ); 94 | } 95 | 96 | 97 | 98 | 99 | 100 | void 101 | print_family_info (struct family_info *proc_info) 102 | { 103 | //print CPU info 104 | printf ("i7z DEBUG: Stepping %x\n", proc_info->stepping); 105 | printf ("i7z DEBUG: Model %x\n", proc_info->model); 106 | printf ("i7z DEBUG: Family %x\n", proc_info->family); 107 | printf ("i7z DEBUG: Processor Type %x\n", proc_info->processor_type); 108 | printf ("i7z DEBUG: Extended Model %x\n", proc_info->extended_model); 109 | // printf(" Extended Family %x\n", (short int*)(&proc_info->extended_family)); 110 | // printf(" Extended Family %d\n", proc_info->extended_family); 111 | } 112 | 113 | 114 | #ifdef x64_BIT 115 | void get_vendor (char *vendor_string) 116 | { 117 | //get vendor name 118 | unsigned int b, c, d, e; 119 | // int i; 120 | asm volatile ("mov %4, %%eax; " // 0 into eax 121 | "cpuid;" "mov %%eax, %0;" // eeax into b 122 | "mov %%ebx, %1;" // eebx into c 123 | "mov %%edx, %2;" // eeax into d 124 | "mov %%ecx, %3;" // eeax into e 125 | :"=r" (b), "=r" (c), "=r" (d), "=r" (e) /* output */ 126 | :"r" (0) /* input */ 127 | :"%eax", "%ebx", "%ecx", "%edx" /* clobbered register, will be modifying inside the asm routine so dont use them */ 128 | ); 129 | memcpy (vendor_string, &c, 4); 130 | memcpy (vendor_string + 4, &d, 4); 131 | memcpy (vendor_string + 8, &e, 4); 132 | vendor_string[12] = '\0'; 133 | // printf("Vendor %s\n",vendor_string); 134 | } 135 | #endif 136 | 137 | int turbo_status () 138 | { 139 | //turbo state flag 140 | unsigned int eax; 141 | // int i; 142 | asm volatile ("mov %1, %%eax; " // 0 into eax 143 | "cpuid;" "mov %%eax, %0;" // eeax into b 144 | :"=r" (eax) /* output */ 145 | :"r" (6) /* input */ 146 | :"%eax" /* clobbered register, will be modifying inside the asm routine so dont use them */ 147 | ); 148 | 149 | //printf("eax %d\n",(eax&0x2)>>1); 150 | 151 | return ((eax & 0x2) >> 1); 152 | } 153 | 154 | void get_familyinformation (struct family_info *proc_info) 155 | { 156 | //get info about CPU 157 | unsigned int b; 158 | asm volatile ("mov %1, %%eax; " // 0 into eax 159 | "cpuid;" "mov %%eax, %0;" // eeax into b 160 | :"=r" (b) /* output */ 161 | :"r" (1) /* input */ 162 | :"%eax" /* clobbered register, will be modifying inside the asm routine so dont use them */ 163 | ); 164 | // printf ("eax %x\n", b); 165 | proc_info->stepping = b & 0x0000000F; //bits 3:0 166 | proc_info->model = (b & 0x000000F0) >> 4; //bits 7:4 167 | proc_info->family = (b & 0x00000F00) >> 8; //bits 11:8 168 | proc_info->processor_type = (b & 0x00007000) >> 12; //bits 13:12 169 | proc_info->extended_model = (b & 0x000F0000) >> 16; //bits 19:16 170 | proc_info->extended_family = (b & 0x0FF00000) >> 20; //bits 27:20 171 | } 172 | 173 | double estimate_MHz () 174 | { 175 | //copied blantantly from http://www.cs.helsinki.fi/linux/linux-kernel/2001-37/0256.html 176 | /* 177 | * $Id: MHz.c,v 1.4 2001/05/21 18:58:01 davej Exp $ 178 | * This file is part of x86info. 179 | * (C) 2001 Dave Jones. 180 | * 181 | * Licensed under the terms of the GNU GPL License version 2. 182 | * 183 | * Estimate CPU MHz routine by Andrea Arcangeli 184 | * Small changes by David Sterba 185 | * 186 | */ 187 | struct timezone tz; 188 | struct timeval tvstart, tvstop; 189 | unsigned long long int cycles[2]; /* gotta be 64 bit */ 190 | unsigned long long int microseconds; /* total time taken */ 191 | 192 | memset (&tz, 0, sizeof (tz)); 193 | 194 | /* get this function in cached memory */ 195 | gettimeofday (&tvstart, &tz); 196 | cycles[0] = rdtsc (); 197 | gettimeofday (&tvstart, &tz); 198 | 199 | /* we don't trust that this is any specific length of time */ 200 | //1 sec will cause rdtsc to overlap multiple times perhaps. 100msecs is a good spot 201 | usleep (100000); 202 | 203 | cycles[1] = rdtsc (); 204 | gettimeofday (&tvstop, &tz); 205 | microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) + 206 | (tvstop.tv_usec - tvstart.tv_usec); 207 | 208 | unsigned long long int elapsed = 0; 209 | if (cycles[1] < cycles[0]) 210 | { 211 | //printf("c0 = %llu c1 = %llu",cycles[0],cycles[1]); 212 | elapsed = UINT32_MAX - cycles[0]; 213 | elapsed = elapsed + cycles[1]; 214 | //printf("c0 = %llu c1 = %llu max = %llu elapsed=%llu\n",cycles[0], cycles[1], UINT32_MAX,elapsed); 215 | } 216 | else 217 | { 218 | elapsed = cycles[1] - cycles[0]; 219 | //printf("\nc0 = %llu c1 = %llu elapsed=%llu\n",cycles[0], cycles[1],elapsed); 220 | } 221 | 222 | double mhz = elapsed / microseconds; 223 | 224 | 225 | //printf("%llg MHz processor (estimate). diff cycles=%llu microseconds=%llu \n", mhz, elapsed, microseconds); 226 | //printf("%g elapsed %llu microseconds %llu\n",mhz, elapsed, microseconds); 227 | return (mhz); 228 | } 229 | 230 | /* Number of decimal digits for a certain number of bits */ 231 | /* (int) ceil(log(2^n)/log(10)) */ 232 | int decdigits[] = { 233 | 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 234 | 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 235 | 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 236 | 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 237 | 20 238 | }; 239 | 240 | #define mo_hex 0x01 241 | #define mo_dec 0x02 242 | #define mo_oct 0x03 243 | #define mo_raw 0x04 244 | #define mo_uns 0x05 245 | #define mo_chx 0x06 246 | #define mo_mask 0x0f 247 | #define mo_fill 0x40 248 | #define mo_c 0x80 249 | 250 | const char *program; 251 | 252 | 253 | uint64_t get_msr_value (int cpu, uint32_t reg, unsigned int highbit, 254 | unsigned int lowbit, int* error_indx) 255 | { 256 | uint64_t data; 257 | int fd; 258 | // char *pat; 259 | // int width; 260 | char msr_file_name[64]; 261 | int bits; 262 | *error_indx =0; 263 | 264 | sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); 265 | fd = open (msr_file_name, O_RDONLY); 266 | if (fd < 0) 267 | { 268 | if (errno == ENXIO) 269 | { 270 | //fprintf (stderr, "rdmsr: No CPU %d\n", cpu); 271 | *error_indx = 1; 272 | return 1; 273 | } else if (errno == EIO) { 274 | //fprintf (stderr, "rdmsr: CPU %d doesn't support MSRs\n", cpu); 275 | *error_indx = 1; 276 | return 1; 277 | } else { 278 | //perror ("rdmsr:open"); 279 | *error_indx = 1; 280 | return 1; 281 | //exit (127); 282 | } 283 | } 284 | 285 | if (pread (fd, &data, sizeof data, reg) != sizeof data) 286 | { 287 | //perror ("rdmsr:pread"); 288 | *error_indx = 1; 289 | return 1; 290 | //exit (127); 291 | } 292 | 293 | close (fd); 294 | 295 | bits = highbit - lowbit + 1; 296 | if (bits < 64) 297 | { 298 | /* Show only part of register */ 299 | data >>= lowbit; 300 | data &= (1ULL << bits) - 1; 301 | } 302 | 303 | /* Make sure we get sign correct */ 304 | if (data & (1ULL << (bits - 1))) 305 | { 306 | data &= ~(1ULL << (bits - 1)); 307 | data = -data; 308 | } 309 | 310 | *error_indx = 0; 311 | return (data); 312 | } 313 | 314 | uint64_t set_msr_value (int cpu, uint32_t reg, uint64_t data, int* error_indx) 315 | { 316 | int fd; 317 | char msr_file_name[64]; 318 | 319 | sprintf (msr_file_name, "/dev/cpu/%d/msr", cpu); 320 | fd = open (msr_file_name, O_WRONLY); 321 | if (fd < 0) 322 | { 323 | if (errno == ENXIO) 324 | { 325 | //fprintf (stderr, "wrmsr: No CPU %d\n", cpu); 326 | //exit (2); 327 | *error_indx = 1; 328 | return 1; 329 | } else if (errno == EIO) { 330 | //fprintf (stderr, "wrmsr: CPU %d doesn't support MSRs\n", cpu); 331 | //exit (3); 332 | *error_indx = 1; 333 | return 1; 334 | } else { 335 | //perror ("wrmsr:open"); 336 | //exit (127); 337 | *error_indx = 1; 338 | return 1; 339 | } 340 | } 341 | 342 | if (pwrite (fd, &data, sizeof data, reg) != sizeof data) 343 | { 344 | //perror ("wrmsr:pwrite"); 345 | //exit (127); 346 | *error_indx = 1; 347 | return 1; 348 | } 349 | close(fd); 350 | return(1); 351 | } 352 | 353 | 354 | #ifdef USE_INTEL_CPUID 355 | void get_CPUs_info (unsigned int *num_Logical_OS, 356 | unsigned int *num_Logical_process, 357 | unsigned int *num_Processor_Core, 358 | 359 | unsigned int *num_Physical_Socket); 360 | 361 | #endif 362 | 363 | 364 | //Below code 365 | /* ----------------------------------------------------------------------- * 366 | * 367 | * Copyright 2010 Abhishek Jaiantilal 368 | * 369 | * Under GPL v2 370 | * 371 | * ----------------------------------------------------------------------- */ 372 | 373 | void Print_Version_Information() 374 | { 375 | printf ("i7z DEBUG: i7z version: %s\n",i7z_VERSION_INFO); 376 | } 377 | 378 | 379 | void Print_Information_Processor() 380 | { 381 | struct family_info proc_info; 382 | 383 | #ifdef x64_BIT 384 | char vendor_string[13]; 385 | get_vendor (vendor_string); 386 | if (strcmp (vendor_string, "GenuineIntel") == 0) 387 | printf ("i7z DEBUG: Found Intel Processor\n"); 388 | else 389 | { 390 | printf 391 | ("this was designed to be a intel proc utility. You can perhaps mod it for your machine?\n"); 392 | exit (1); 393 | } 394 | #endif 395 | 396 | #ifndef x64_BIT 397 | //anecdotal evidence: get_vendor doesnt seem to work on 32-bit 398 | printf 399 | ("I dont know the CPUID code to check on 32-bit OS, so i will assume that you have an Intel processor\n"); 400 | printf ("Don't worry if i don't find a nehalem next, i'll quit anyways\n"); 401 | #endif 402 | 403 | get_familyinformation (&proc_info); 404 | print_family_info (&proc_info); 405 | 406 | //printf("%x %x",proc_info.extended_model,proc_info.family); 407 | 408 | //check if its nehalem or exit 409 | //Info from page 641 of Intel Manual 3B 410 | //Extended model and Model can help determine the right cpu 411 | printf("i7z DEBUG: msr = Model Specific Register\n"); 412 | if (proc_info.family == 0x6) 413 | { 414 | if (proc_info.extended_model == 0x1) 415 | { 416 | switch (proc_info.model) 417 | { 418 | case 0xA: 419 | printf ("i7z DEBUG: Detected a nehalem (i7)\n"); 420 | break; 421 | case 0xE: 422 | case 0xF: 423 | printf ("i7z DEBUG: Detected a nehalem (i7/i5)\n"); 424 | break; 425 | default: 426 | printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); 427 | exit (1); 428 | } 429 | } else if (proc_info.extended_model == 0x2) 430 | { 431 | switch (proc_info.model) 432 | { 433 | case 0xE: 434 | printf ("i7z DEBUG: Detected a nehalem (Xeon)\n"); 435 | break; 436 | case 0x5: 437 | case 0xC: 438 | printf ("i7z DEBUG: Detected a nehalem (32nm Westmere)\n"); 439 | break; 440 | default: 441 | printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); 442 | exit (1); 443 | } 444 | } else { 445 | printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); 446 | exit (1); 447 | } 448 | } else { 449 | printf ("i7z DEBUG: Unknown processor, not exactly based on Nehalem\n"); 450 | exit (1); 451 | } 452 | 453 | } 454 | 455 | void Test_Or_Make_MSR_DEVICE_FILES() 456 | { 457 | //test if the msr file exists 458 | if (access ("/dev/cpu/0/msr", F_OK) == 0) 459 | { 460 | printf ("i7z DEBUG: msr device files exist /dev/cpu/*/msr\n"); 461 | if (access ("/dev/cpu/0/msr", W_OK) == 0) 462 | { 463 | //a system mght have been set with msr allowable to be written 464 | //by a normal user so... 465 | //Do nothing. 466 | printf ("i7z DEBUG: You have write permissions to msr device files\n"); 467 | } else { 468 | printf ("i7z DEBUG: You DONOT have write permissions to msr device files\n"); 469 | printf ("i7z DEBUG: A solution is to run this program as root\n"); 470 | exit (1); 471 | } 472 | } else { 473 | printf ("i7z DEBUG: msr device files DONOT exist, trying out a makedev script\n"); 474 | if (geteuid () == 0) 475 | { 476 | //Try the Makedev script 477 | system ("msr_major=202; \ 478 | cpuid_major=203; \ 479 | n=0; \ 480 | while [ $n -lt 16 ]; do \ 481 | mkdir -m 0755 -p /dev/cpu/$n; \ 482 | mknod /dev/cpu/$n/msr -m 0600 c $msr_major $n; \ 483 | mknod /dev/cpu/$n/cpuid -m 0444 c $cpuid_major $n; \ 484 | n=`expr $n + 1`; \ 485 | done; \ 486 | "); 487 | printf ("i7z DEBUG: modprobbing for msr\n"); 488 | system ("modprobe msr"); 489 | } else { 490 | printf ("i7z DEBUG: You DONOT have root privileges, mknod to create device entries won't work out\n"); 491 | printf ("i7z DEBUG: A solution is to run this program as root\n"); 492 | exit (1); 493 | } 494 | } 495 | } 496 | double cpufreq_info() 497 | { 498 | //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present 499 | //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID 500 | //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ 501 | system 502 | ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); 503 | 504 | 505 | //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo 506 | FILE *tmp_file; 507 | tmp_file = fopen ("/tmp/cpufreq.txt", "r"); 508 | char tmp_str[30]; 509 | fgets (tmp_str, 30, tmp_file); 510 | fclose (tmp_file); 511 | return atof(tmp_str); 512 | } 513 | 514 | int check_and_return_processor(char*strinfo) 515 | { 516 | char *t1; 517 | if (strstr(strinfo,"processor") !=NULL) { 518 | strtok(strinfo,":"); 519 | t1 = strtok(NULL, " "); 520 | return(atoi(t1)); 521 | } else { 522 | return(-1); 523 | } 524 | } 525 | 526 | int check_and_return_physical_id(char*strinfo) 527 | { 528 | char *t1; 529 | if (strstr(strinfo,"physical id") !=NULL) { 530 | strtok(strinfo,":"); 531 | t1 = strtok(NULL, " "); 532 | return(atoi(t1)); 533 | } else { 534 | return(-1); 535 | } 536 | } 537 | 538 | int check_and_return_core_id(char*strinfo) 539 | { 540 | char *t1; 541 | if (strstr(strinfo,"core id") !=NULL) { 542 | strtok(strinfo,":"); 543 | t1 = strtok(NULL, " "); 544 | return(atoi(t1)); 545 | } else { 546 | return(-1); 547 | } 548 | } 549 | 550 | void construct_sibling_list(struct cpu_heirarchy_info* chi) 551 | { 552 | int i,j,core_id,socket_id; 553 | for (i=0;i< chi->max_online_cpu ;i++) { 554 | assert(i < MAX_HI_PROCESSORS); 555 | chi->sibling_num[i]=-1; 556 | } 557 | 558 | chi->HT=false; 559 | for (i=0;i< chi->max_online_cpu ;i++) { 560 | assert(i < MAX_HI_PROCESSORS); 561 | core_id = chi->coreid_num[i]; 562 | socket_id = chi->package_num[i]; 563 | for (j=i+1;j< chi->max_online_cpu ;j++) { 564 | assert(j < MAX_HI_PROCESSORS); 565 | if (chi->coreid_num[j] == core_id && chi->package_num[j] == socket_id) { 566 | chi->sibling_num[j] = i; 567 | chi->sibling_num[i] = j; 568 | chi->display_cores[i] = 1; 569 | chi->display_cores[j] = -1; 570 | chi->HT=true; 571 | continue; 572 | } 573 | } 574 | } 575 | //for cores that donot have a sibling put in 1 576 | for (i=0;i< chi->max_online_cpu ;i++) { 577 | assert(i < MAX_HI_PROCESSORS); 578 | if (chi->sibling_num[i] ==-1) 579 | chi->display_cores[i] = 1; 580 | } 581 | } 582 | 583 | void construct_socket_information(struct cpu_heirarchy_info* chi,struct cpu_socket_info* socket_0,struct cpu_socket_info* socket_1) 584 | { 585 | int i; 586 | 587 | socket_0->max_cpu=0; 588 | socket_0->num_physical_cores=0; 589 | socket_0->num_logical_cores=0; 590 | socket_1->max_cpu=0; 591 | socket_1->num_physical_cores=0; 592 | socket_1->num_logical_cores=0; 593 | 594 | 595 | for (i=0;i< chi->max_online_cpu ;i++) { 596 | assert(i < MAX_HI_PROCESSORS); 597 | if (chi->display_cores[i]!=-1) { 598 | if (chi->package_num[i]==0) { 599 | assert(socket_0->max_cpu < MAX_SK_PROCESSORS); 600 | socket_0->processor_num[socket_0->max_cpu]=chi->processor_num[i]; 601 | socket_0->max_cpu++; 602 | socket_0->num_physical_cores++; 603 | socket_0->num_logical_cores++; 604 | } 605 | if (chi->package_num[i]==1) { 606 | assert(socket_1->max_cpu < MAX_SK_PROCESSORS); 607 | socket_1->processor_num[socket_1->max_cpu]=chi->processor_num[i]; 608 | socket_1->max_cpu++; 609 | socket_1->num_physical_cores++; 610 | socket_1->num_logical_cores++; 611 | } 612 | } else { 613 | if (chi->package_num[i]==0) { 614 | socket_0->num_logical_cores++; 615 | } 616 | if (chi->package_num[i]==1) { 617 | socket_1->num_logical_cores++; 618 | } 619 | } 620 | } 621 | } 622 | 623 | void print_socket_information(struct cpu_socket_info* socket) 624 | { 625 | int i; 626 | char socket_list[200]=""; 627 | 628 | for (i=0;i< socket->max_cpu ;i++) { 629 | assert(i < MAX_SK_PROCESSORS); 630 | if (socket->processor_num[i]!=-1) { 631 | sprintf(socket_list,"%s%d,",socket_list,socket->processor_num[i]); 632 | } 633 | } 634 | 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); 635 | } 636 | 637 | void construct_CPU_Heirarchy_info(struct cpu_heirarchy_info* chi) 638 | { 639 | FILE *fp = fopen("/proc/cpuinfo","r"); 640 | char strinfo[200]; 641 | 642 | int processor_num, physicalid_num, coreid_num; 643 | int it_processor_num=-1, it_physicalid_num=-1, it_coreid_num=-1; 644 | int tmp_processor_num, tmp_physicalid_num, tmp_coreid_num; 645 | int old_processor_num=-1; 646 | 647 | memset(chi, 0, sizeof(*chi)); 648 | 649 | if (fp!=NULL) { 650 | while ( fgets(strinfo,200,fp) != NULL) { 651 | // printf(strinfo); 652 | tmp_processor_num = check_and_return_processor(strinfo); 653 | tmp_physicalid_num = check_and_return_physical_id(strinfo); 654 | tmp_coreid_num = check_and_return_core_id(strinfo); 655 | 656 | 657 | if (tmp_processor_num != -1) { 658 | it_processor_num++; 659 | processor_num = tmp_processor_num; 660 | assert(it_processor_num < MAX_HI_PROCESSORS); 661 | chi->processor_num[it_processor_num] = processor_num; 662 | } 663 | if (tmp_physicalid_num != -1) { 664 | it_physicalid_num++; 665 | physicalid_num = tmp_physicalid_num; 666 | assert(it_physicalid_num < MAX_HI_PROCESSORS); 667 | chi->package_num[it_physicalid_num] = physicalid_num; 668 | } 669 | if (tmp_coreid_num != -1) { 670 | it_coreid_num++; 671 | coreid_num = tmp_coreid_num; 672 | assert(it_coreid_num < MAX_HI_PROCESSORS); 673 | chi->coreid_num[it_coreid_num] = coreid_num; 674 | } 675 | if (processor_num != old_processor_num) { 676 | old_processor_num = processor_num; 677 | } 678 | } 679 | } 680 | chi->max_online_cpu = it_processor_num+1; 681 | fclose(fp); 682 | } 683 | 684 | void print_CPU_Heirarchy(struct cpu_heirarchy_info chi) 685 | { 686 | int i; 687 | printf("\n------------------------------\n--[core id]--- Other information\n-------------------------------------\n"); 688 | for (i=0;i < chi.max_online_cpu;i++) { 689 | assert(i < MAX_HI_PROCESSORS); 690 | printf("--[%d] Processor number %d\n",i,chi.processor_num[i]); 691 | printf("--[%d] Socket number/Hyperthreaded Sibling number %d,%d\n",i,chi.package_num[i],chi.sibling_num[i]); 692 | printf("--[%d] Core id number %d\n",i,chi.coreid_num[i]); 693 | printf("--[%d] Display core in i7z Tool: %s\n\n",i,(chi.display_cores[i]==1)?"Yes":"No"); 694 | } 695 | } 696 | 697 | int in_core_list(int ii,int* core_list) 698 | { 699 | int i; 700 | int in=0; 701 | for (i=0;i<8;i++) { 702 | if (ii == core_list[i]) { 703 | in=1; 704 | break; 705 | } 706 | } 707 | return(in); 708 | } 709 | 710 | -------------------------------------------------------------------------------- /src/GUI/i7z_GUI.cpp: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- * 2 | * 3 | * Copyright 2009 Abhishek Jaiantilal 4 | * 5 | * Under GPL v2 6 | * 7 | * ----------------------------------------------------------------------- */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | #ifndef UINT32_MAX 34 | # define UINT32_MAX (4294967295U) 35 | #endif 36 | extern "C" { 37 | #include "../helper_functions.c" 38 | } 39 | 40 | #define MAX_PROCESSORS_GUI 12 41 | 42 | bool global_in_i7z_main_thread = false; 43 | int socket_list[MAX_PROCESSORS_GUI]; 44 | int core_list[MAX_PROCESSORS_GUI]; 45 | struct cpu_hierarchy_info chi; 46 | struct cpu_socket_info socket_0, socket_1; 47 | unsigned int numCPUs; 48 | struct program_options prog_options; 49 | 50 | void Construct_Socket_Information_in_GUI(unsigned int *numCPUs) { 51 | int socket_0_num=0, socket_1_num=1; 52 | socket_0.max_cpu=0; 53 | socket_0.socket_num=0; 54 | int i; 55 | for(i=0;i < 8; i++) 56 | socket_0.processor_num[i]=-1; 57 | socket_1.max_cpu=0; 58 | socket_1.socket_num=1; 59 | 60 | for(i=0;i < 8; i++) 61 | socket_1.processor_num[i]=-1; 62 | 63 | construct_CPU_Hierarchy_info(&chi); 64 | construct_sibling_list(&chi); 65 | // print_CPU_Hierarchy(chi); 66 | construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); 67 | // print_socket_information(&socket_0); 68 | // print_socket_information(&socket_1); 69 | *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; 70 | 71 | //// FOR DEBUGGING DUAL SOCKET CODE ON SINGLE SOCKET, UNCOMMENT BELOW 2 lines 72 | // memcpy(&socket_1, &socket_0, sizeof(struct cpu_socket_info)); 73 | // socket_1.socket_num=0; 74 | 75 | 76 | // print_socket_information(&socket_0); 77 | // print_socket_information(&socket_1); 78 | *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; 79 | // printf("My Widget: Num Processors %d\n",*numCPUs); 80 | 81 | int k, ii; 82 | k=0; 83 | for (ii = 0; ii < socket_0.num_physical_cores ; ii++) { 84 | if ( socket_0.processor_num[ii] != -1) { 85 | core_list[k] = socket_0.processor_num[ii]; 86 | socket_list[k] = 0; 87 | k++; 88 | } 89 | } 90 | for (ii = 0; ii < socket_1.num_physical_cores ; ii++) { 91 | if ( socket_1.processor_num[ii] != -1) { 92 | core_list[k] = socket_1.processor_num[ii]; 93 | socket_list[k] = 1; 94 | k++; 95 | } 96 | } 97 | } 98 | 99 | class MyThread:public QThread 100 | { 101 | public: 102 | MyThread (); 103 | void run (); 104 | double *FREQ, *MULT; 105 | long double *C0_TIME, *C1_TIME, *C3_TIME, *C6_TIME; 106 | }; 107 | 108 | MyThread::MyThread () 109 | { 110 | Construct_Socket_Information_in_GUI(&numCPUs); 111 | 112 | //allocate space for the variables 113 | FREQ = (double *) malloc (sizeof (double) * numCPUs); 114 | MULT = (double *) malloc (sizeof (double) * numCPUs); 115 | C0_TIME = (long double *) malloc (sizeof (long double) * numCPUs); 116 | C1_TIME = (long double *) malloc (sizeof (long double) * numCPUs); 117 | C3_TIME = (long double *) malloc (sizeof (long double) * numCPUs); 118 | C6_TIME = (long double *) malloc (sizeof (long double) * numCPUs); 119 | 120 | int i; 121 | for (i = 0; i < (int)numCPUs; i++) 122 | { 123 | FREQ[i] = 0; 124 | MULT[i] = 0; 125 | C0_TIME[i] = 0; 126 | C1_TIME[i] = 0; 127 | C3_TIME[i] = 0; 128 | C6_TIME[i] = 0; 129 | } 130 | } 131 | 132 | 133 | void 134 | MyThread::run () 135 | { 136 | 137 | print_CPU_Hierarchy(chi); 138 | 139 | int i, ii; 140 | 141 | //MSR number and hi:low bit of that MSR 142 | //This msr contains a lot of stuff, per socket wise 143 | //one can pass any core number and then get in multiplier etc 144 | int PLATFORM_INFO_MSR = 206; //CE 15:8 145 | int PLATFORM_INFO_MSR_low = 8; 146 | int PLATFORM_INFO_MSR_high = 15; 147 | 148 | ////To find out if Turbo is enabled use the below msr and bit 38 149 | ////bit for TURBO is 38 150 | ////msr reading is now moved into tubo_status 151 | //int IA32_MISC_ENABLE = 416; 152 | //int TURBO_FLAG_low = 38; 153 | //int TURBO_FLAG_high = 38; 154 | 155 | 156 | //int MSR_TURBO_RATIO_LIMIT = 429; 157 | 158 | int CPU_NUM; 159 | int CPU_Multiplier; 160 | float BLCK; 161 | char TURBO_MODE; 162 | 163 | printf("i7z DEBUG: GUI VERSION DOESN'T SUPPORT CORE OFFLINING\n"); 164 | sleep (1); 165 | 166 | // 3B defines till Max 4 Core and the rest bit values from 32:63 were reserved. 167 | // int MAX_TURBO_1C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 7, 0); 168 | // int MAX_TURBO_2C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 15, 8); 169 | // int MAX_TURBO_3C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 23, 16); 170 | // int MAX_TURBO_4C = get_msr_value (CPU_NUM, MSR_TURBO_RATIO_LIMIT, 31, 24); 171 | 172 | 173 | //CPUINFO is wrong for i7 but correct for the number of physical and logical cores present 174 | //If Hyperthreading is enabled then, multiple logical processors will share a common CORE ID 175 | //http://www.redhat.com/magazine/022aug06/departments/tips_tricks/ 176 | system ("cat /proc/cpuinfo |grep MHz|sed 's/cpu\\sMHz\\s*:\\s//'|tail -n 1 > /tmp/cpufreq.txt"); 177 | system ("grep \"core id\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numPhysical.txt"); 178 | system ("grep \"processor\" /proc/cpuinfo |sort -|uniq -|wc -l > /tmp/numLogical.txt"); 179 | 180 | 181 | //Open the parsed cpufreq file and obtain the cpufreq from /proc/cpuinfo 182 | FILE *tmp_file; 183 | tmp_file = fopen ("/tmp/cpufreq.txt", "r"); 184 | char tmp_str[30]; 185 | fgets (tmp_str, 30, tmp_file); 186 | double cpu_freq_cpuinfo = atof (tmp_str); 187 | fclose (tmp_file); 188 | 189 | unsigned int numPhysicalCores, numLogicalCores; 190 | numPhysicalCores = socket_0.num_physical_cores + socket_1.num_physical_cores; 191 | numLogicalCores = socket_0.num_logical_cores + socket_1.num_logical_cores; 192 | // printf("My thread: Num Processors %d\n",numCPUs); 193 | 194 | int error_indx; 195 | 196 | //estimate the freq using the estimate_MHz() code that is almost mhz accurate 197 | cpu_freq_cpuinfo = estimate_MHz (); 198 | 199 | //We just need one CPU (we use Core-0) to figure out the multiplier and the bus clock freq. 200 | CPU_NUM = 0; 201 | CPU_Multiplier = 202 | get_msr_value (CPU_NUM, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, 203 | PLATFORM_INFO_MSR_low, &error_indx); 204 | BLCK = cpu_freq_cpuinfo / CPU_Multiplier; 205 | TURBO_MODE = turbo_status (); //get_msr_value(CPU_NUM,IA32_MISC_ENABLE, TURBO_FLAG_high,TURBO_FLAG_low); 206 | 207 | //to find how many cpus are enabled, we could have used sysconf but that will just give the logical numbers 208 | //if HT is enabled then the threads of the same core have the same C-state residency number so... 209 | //Its imperative to figure out the number of physical and number of logical cores. 210 | //sysconf(_SC_NPROCESSORS_ONLN); 211 | 212 | 213 | bool HT_ON; 214 | char HT_ON_str[30]; 215 | if (numLogicalCores > numPhysicalCores) 216 | { 217 | strcpy (HT_ON_str, "Hyper Threading ON"); 218 | HT_ON = true; 219 | } 220 | else 221 | { 222 | strcpy (HT_ON_str, "Hyper Threading OFF"); 223 | HT_ON = false; 224 | } 225 | 226 | float TRUE_CPU_FREQ; 227 | if (TURBO_MODE == 1) 228 | { 229 | TRUE_CPU_FREQ = BLCK * ((double)CPU_Multiplier + 1); 230 | } 231 | else 232 | { 233 | TRUE_CPU_FREQ = BLCK * ((double)CPU_Multiplier); 234 | } 235 | 236 | 237 | int IA32_PERF_GLOBAL_CTRL = 911; //3BF 238 | int IA32_PERF_GLOBAL_CTRL_Value = 239 | get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0,&error_indx); 240 | int IA32_FIXED_CTR_CTL = 909; //38D 241 | int IA32_FIXED_CTR_CTL_Value = 242 | get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0,&error_indx); 243 | 244 | //printf("IA32_PERF_GLOBAL_CTRL %d\n",IA32_PERF_GLOBAL_CTRL_Value); 245 | //printf("IA32_FIXED_CTR_CTL %d\n",IA32_FIXED_CTR_CTL_Value); 246 | 247 | unsigned long long int CPU_CLK_UNHALTED_CORE, CPU_CLK_UNHALTED_REF, 248 | CPU_CLK_C3, CPU_CLK_C6, CPU_CLK_C1; 249 | 250 | CPU_CLK_UNHALTED_CORE = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); 251 | CPU_CLK_UNHALTED_REF = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); 252 | 253 | unsigned long long int old_val_CORE[numCPUs], new_val_CORE[numCPUs]; 254 | unsigned long long int old_val_REF[numCPUs], new_val_REF[numCPUs]; 255 | unsigned long long int old_val_C3[numCPUs], new_val_C3[numCPUs]; 256 | unsigned long long int old_val_C6[numCPUs], new_val_C6[numCPUs]; 257 | // unsigned long int old_val_C1[numCPUs], new_val_C1[numCPUs]; 258 | 259 | unsigned long long int old_TSC[numCPUs], new_TSC[numCPUs]; 260 | 261 | struct timeval tvstart[numCPUs], tvstop[numCPUs]; 262 | 263 | struct timespec one_second_sleep; 264 | one_second_sleep.tv_sec = 0; 265 | one_second_sleep.tv_nsec = 999999999; // 1000msec 266 | 267 | 268 | unsigned long int IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0,&error_indx); 269 | unsigned long int IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0,&error_indx); 270 | // mvprintw(12,0,"Wait...\n"); refresh(); 271 | nanosleep (&one_second_sleep, NULL); 272 | IA32_MPERF = get_msr_value (CPU_NUM, 231, 7, 0, &error_indx) - IA32_MPERF; 273 | IA32_APERF = get_msr_value (CPU_NUM, 232, 7, 0, &error_indx) - IA32_APERF; 274 | 275 | //printf("Diff. i n APERF = %u, MPERF = %d\n", IA32_MPERF, IA32_APERF); 276 | 277 | long double C0_time[numCPUs], C1_time[numCPUs], C3_time[numCPUs], C6_time[numCPUs]; 278 | double _FREQ[numCPUs], _MULT[numCPUs]; 279 | 280 | // mvprintw(12,0,"Current Freqs\n"); 281 | 282 | int kk=11; 283 | double estimated_mhz; 284 | for (;;) 285 | { 286 | Construct_Socket_Information_in_GUI(&numCPUs); 287 | 288 | if (kk>10) { 289 | kk=0; 290 | for (ii = 0; ii < (int)numCPUs; ii++) 291 | { 292 | CPU_NUM = core_list[ii]; 293 | IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); 294 | set_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 0x700000003LLU); 295 | 296 | IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); 297 | set_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 819); 298 | 299 | IA32_PERF_GLOBAL_CTRL_Value = get_msr_value (CPU_NUM, IA32_PERF_GLOBAL_CTRL, 63, 0, &error_indx); 300 | IA32_FIXED_CTR_CTL_Value = get_msr_value (CPU_NUM, IA32_FIXED_CTR_CTL, 63, 0, &error_indx); 301 | 302 | old_val_CORE[ii] = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); 303 | old_val_REF[ii] = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); 304 | old_val_C3[ii] = get_msr_value (CPU_NUM, 1020, 63, 0,&error_indx); 305 | old_val_C6[ii] = get_msr_value (CPU_NUM, 1021, 63, 0,&error_indx); 306 | old_TSC[ii] = rdtsc (); 307 | } 308 | } 309 | kk++; 310 | 311 | nanosleep (&one_second_sleep, NULL); 312 | 313 | estimated_mhz = estimate_MHz(); 314 | 315 | for (i = 0; i < (int)numCPUs; i++) 316 | { 317 | CPU_NUM = core_list[i]; 318 | new_val_CORE[i] = get_msr_value (CPU_NUM, 778, 63, 0,&error_indx); 319 | new_val_REF[i] = get_msr_value (CPU_NUM, 779, 63, 0,&error_indx); 320 | new_val_C3[i] = get_msr_value (CPU_NUM, 1020, 63, 0,&error_indx); 321 | new_val_C6[i] = get_msr_value (CPU_NUM, 1021, 63, 0,&error_indx); 322 | new_TSC[i] = rdtsc (); 323 | if (old_val_CORE[i] > new_val_CORE[i]) 324 | { 325 | CPU_CLK_UNHALTED_CORE = 326 | (3.40282366921e38 - old_val_CORE[i]) + new_val_CORE[i]; 327 | } 328 | else 329 | { 330 | CPU_CLK_UNHALTED_CORE = new_val_CORE[i] - old_val_CORE[i]; 331 | } 332 | 333 | //number of TSC cycles while its in halted state 334 | if ((new_TSC[i] - old_TSC[i]) < CPU_CLK_UNHALTED_CORE) 335 | CPU_CLK_C1 = 0; 336 | else 337 | CPU_CLK_C1 = ((new_TSC[i] - old_TSC[i]) - CPU_CLK_UNHALTED_CORE); 338 | 339 | if (old_val_REF[i] > new_val_REF[i]) 340 | { 341 | CPU_CLK_UNHALTED_REF = 342 | (3.40282366921e38 - old_val_REF[i]) + new_val_REF[i]; 343 | } 344 | else 345 | { 346 | CPU_CLK_UNHALTED_REF = new_val_REF[i] - old_val_REF[i]; 347 | } 348 | 349 | if (old_val_C3[i] > new_val_C3[i]) 350 | { 351 | CPU_CLK_C3 = (3.40282366921e38 - old_val_C3[i]) + new_val_C3[i]; 352 | } 353 | else 354 | { 355 | CPU_CLK_C3 = new_val_C3[i] - old_val_C3[i]; 356 | } 357 | 358 | if (old_val_C6[i] > new_val_C6[i]) 359 | { 360 | CPU_CLK_C6 = (3.40282366921e38 - old_val_C6[i]) + new_val_C6[i]; 361 | } 362 | else 363 | { 364 | CPU_CLK_C6 = new_val_C6[i] - old_val_C6[i]; 365 | } 366 | 367 | _FREQ[i] = 368 | estimated_mhz * ((long double) CPU_CLK_UNHALTED_CORE / 369 | (long double) CPU_CLK_UNHALTED_REF); 370 | _MULT[i] = _FREQ[i] / BLCK; 371 | 372 | C0_time[i] = 373 | ((long double) CPU_CLK_UNHALTED_REF / 374 | (long double) (new_TSC[i] - old_TSC[i])); 375 | long double c1_time = 376 | ((long double) CPU_CLK_C1 / 377 | (long double) (new_TSC[i] - old_TSC[i])); 378 | C3_time[i] = 379 | ((long double) CPU_CLK_C3 / 380 | (long double) (new_TSC[i] - old_TSC[i])); 381 | C6_time[i] = 382 | ((long double) CPU_CLK_C6 / 383 | (long double) (new_TSC[i] - old_TSC[i])); 384 | 385 | //C1_time[i] -= C3_time[i] + C6_time[i]; 386 | C1_time[i] = c1_time - (C3_time[i] + C6_time[i]) ; 387 | if (!isnan(c1_time) && !isinf(c1_time)) { 388 | if (C1_time[i] <= 0) { 389 | C1_time[i]=0; 390 | } 391 | } 392 | 393 | if (C0_time[i] < 1e-2) { 394 | if (C0_time[i] > 1e-4) C0_time[i] = 0.01; 395 | else C0_time[i] = 0; 396 | } 397 | 398 | if (C1_time[i] < 1e-2) { 399 | if (C1_time[i] > 1e-4) C1_time[i] = 0.01; 400 | else C1_time[i] = 0; 401 | } 402 | 403 | if (C3_time[i] < 1e-2) { 404 | if (C3_time[i] > 1e-4) C3_time[i] = 0.01; 405 | else C3_time[i] = 0; 406 | } 407 | 408 | if (C6_time[i] < 1e-2) { 409 | if (C6_time[i] > 1e-4) C6_time[i] = 0.01; 410 | else C6_time[i] = 0; 411 | } 412 | } 413 | // printf("Hello"); 414 | // for(i=0;i TRUE_CPU_FREQ) 422 | TRUE_CPU_FREQ = _FREQ[i]; 423 | 424 | memcpy (old_val_CORE, new_val_CORE, sizeof (unsigned long int) * numCPUs); 425 | memcpy (old_val_REF, new_val_REF, sizeof (unsigned long int) * numCPUs); 426 | memcpy (old_val_C3, new_val_C3, sizeof (unsigned long int) * numCPUs); 427 | memcpy (old_val_C6, new_val_C6, sizeof (unsigned long int) * numCPUs); 428 | memcpy (tvstart, tvstop, sizeof (struct timeval) * numCPUs); 429 | memcpy (old_TSC, new_TSC, sizeof (unsigned long long int) * numCPUs); 430 | 431 | memcpy (FREQ, _FREQ, sizeof (double) * numCPUs); 432 | memcpy (MULT, _MULT, sizeof (double) * numCPUs); 433 | memcpy (C0_TIME, C0_time, sizeof (long double) * numCPUs); 434 | memcpy (C1_TIME, C1_time, sizeof (long double) * numCPUs); 435 | memcpy (C3_TIME, C3_time, sizeof (long double) * numCPUs); 436 | memcpy (C6_TIME, C6_time, sizeof (long double) * numCPUs); 437 | global_in_i7z_main_thread = true; 438 | } 439 | 440 | } 441 | 442 | class MyWidget:public QWidget 443 | { 444 | Q_OBJECT public: 445 | QProgressBar * C0_l[MAX_PROCESSORS_GUI], *C1_l[MAX_PROCESSORS_GUI], *C3_l[MAX_PROCESSORS_GUI], *C6_l[MAX_PROCESSORS_GUI]; 446 | QLabel *C0, *C1, *C3, *C6; 447 | QLabel *Freq_[MAX_PROCESSORS_GUI]; 448 | QLabel *StatusMessage0, *StatusMessage1, *Curr_Freq0, *Curr_Freq1; 449 | QLabel *ProcNames[MAX_PROCESSORS_GUI]; 450 | MyWidget (QWidget * parent = 0); 451 | MyThread *mythread; 452 | int curr_numCPUs; 453 | 454 | private slots: 455 | void UpdateWidget (); 456 | }; 457 | 458 | MyWidget::MyWidget (QWidget * parent):QWidget (parent) 459 | { 460 | 461 | // 462 | //Print_Information_Processor (); 463 | bool cpuNehalem, cpuSandybridge, cpuIvybridge, cpuHaswell; 464 | Print_Information_Processor (&cpuNehalem, &cpuSandybridge, &cpuIvybridge, &cpuHaswell); 465 | 466 | Test_Or_Make_MSR_DEVICE_FILES (); 467 | 468 | Construct_Socket_Information_in_GUI(&numCPUs); 469 | 470 | char processor_str[100]; 471 | // printf("MyWidget: Num Processors %d\n",numCPUs); 472 | int i; 473 | 474 | for (i = 0; i < (int)numCPUs; i++) 475 | { 476 | C0_l[i] = new QProgressBar; 477 | C0_l[i]->setMaximum (99); 478 | C0_l[i]->setMinimum (0); 479 | C1_l[i] = new QProgressBar; 480 | C1_l[i]->setMaximum (99); 481 | C1_l[i]->setMinimum (0); 482 | C3_l[i] = new QProgressBar; 483 | C3_l[i]->setMaximum (99); 484 | C3_l[i]->setMinimum (0); 485 | C6_l[i] = new QProgressBar; 486 | C6_l[i]->setMaximum (99); 487 | C6_l[i]->setMinimum (0); 488 | Freq_[i] = new QLabel (tr ("")); 489 | } 490 | 491 | QGridLayout * layout1 = new QGridLayout; 492 | 493 | curr_numCPUs = numCPUs; 494 | for (i = 0; i < (int)numCPUs; i++) 495 | { 496 | layout1->addWidget (C0_l[i], i + 1, 1); 497 | layout1->addWidget (C1_l[i], i + 1, 2); 498 | layout1->addWidget (C3_l[i], i + 1, 3); 499 | layout1->addWidget (C6_l[i], i + 1, 4); 500 | } 501 | 502 | C0 = new QLabel (tr ("C0")); 503 | C0->setAlignment (Qt::AlignCenter); 504 | C1 = new QLabel (tr ("C1")); 505 | C1->setAlignment (Qt::AlignCenter); 506 | C3 = new QLabel (tr ("C3")); 507 | C3->setAlignment (Qt::AlignCenter); 508 | C6 = new QLabel (tr ("C6")); 509 | C6->setAlignment (Qt::AlignCenter); 510 | 511 | snprintf(processor_str, 100, "Core-1 [id:%d,socket:%d]",core_list[0],socket_list[0]); 512 | ProcNames[0] = new QLabel (tr (processor_str)); 513 | 514 | snprintf(processor_str, 100, "Core-2 [id:%d,socket:%d]",core_list[1],socket_list[1]); 515 | ProcNames[1] = new QLabel (tr (processor_str)); 516 | 517 | snprintf(processor_str, 100, "Core-3 [id:%d,socket:%d]",core_list[2],socket_list[2]); 518 | ProcNames[2] = new QLabel (tr (processor_str)); 519 | 520 | snprintf(processor_str, 100, "Core-4 [id:%d,socket:%d]",core_list[3],socket_list[3]); 521 | ProcNames[3] = new QLabel (tr (processor_str)); 522 | 523 | snprintf(processor_str, 100, "Core-5 [id:%d,socket:%d]",core_list[4],socket_list[4]); 524 | ProcNames[4] = new QLabel (tr (processor_str)); 525 | 526 | snprintf(processor_str, 100, "Core-6 [id:%d,socket:%d]",core_list[5],socket_list[5]); 527 | ProcNames[5] = new QLabel (tr (processor_str)); 528 | 529 | snprintf(processor_str, 100, "Core-7 [id:%d,socket:%d]",core_list[6],socket_list[6]); 530 | ProcNames[6] = new QLabel (tr (processor_str)); 531 | 532 | snprintf(processor_str, 100, "Core-8 [id:%d,socket:%d]",core_list[7],socket_list[7]); 533 | ProcNames[7] = new QLabel (tr (processor_str)); 534 | 535 | snprintf(processor_str, 100, "Core-9 [id:%d,socket:%d]",core_list[8],socket_list[8]); 536 | ProcNames[8] = new QLabel (tr (processor_str)); 537 | 538 | snprintf(processor_str, 100, "Core-10 [id:%d,socket:%d]",core_list[9],socket_list[9]); 539 | ProcNames[9] = new QLabel (tr (processor_str)); 540 | 541 | snprintf(processor_str, 100, "Core-11 [id:%d,socket:%d]",core_list[10],socket_list[10]); 542 | ProcNames[10] = new QLabel (tr (processor_str)); 543 | 544 | snprintf(processor_str, 100, "Core-12 [id:%d,socket:%d]",core_list[11],socket_list[11]); 545 | ProcNames[11] = new QLabel (tr (processor_str)); 546 | 547 | StatusMessage0 = new QLabel (tr ("Wait")); 548 | Curr_Freq0 = new QLabel (tr ("Wait")); 549 | 550 | if ( (socket_0.num_physical_cores > 0) && (socket_1.num_physical_cores > 0)) { 551 | StatusMessage1 = new QLabel (tr ("Wait")); 552 | Curr_Freq1 = new QLabel (tr ("Wait")); 553 | } 554 | 555 | for (i = 0; i < (int)numCPUs; i++) { 556 | layout1->addWidget (ProcNames[i], i + 1, 0); 557 | } 558 | 559 | layout1->addWidget (C0, 0, 1); 560 | layout1->addWidget (C1, 0, 2); 561 | layout1->addWidget (C3, 0, 3); 562 | layout1->addWidget (C6, 0, 4); 563 | 564 | for (i = 0; i < (int)numCPUs; i++) 565 | layout1->addWidget (Freq_[i], i + 1, 5); 566 | 567 | layout1->addWidget (StatusMessage0, numCPUs + 1, 4); 568 | layout1->addWidget (Curr_Freq0, numCPUs + 1, 5); 569 | if ( (socket_0.num_physical_cores > 0) && (socket_1.num_physical_cores > 0)) { 570 | layout1->addWidget (StatusMessage1, numCPUs + 2, 4); 571 | layout1->addWidget (Curr_Freq1, numCPUs + 2, 5); 572 | } 573 | QTimer *timer = new QTimer (this); 574 | connect (timer, SIGNAL (timeout ()), this, SLOT (UpdateWidget ())); 575 | timer->start (1000); 576 | 577 | mythread = new MyThread (); 578 | mythread->start (); 579 | 580 | setLayout (layout1); 581 | } 582 | 583 | void 584 | MyWidget::UpdateWidget () 585 | { 586 | char processor_str[100]; 587 | snprintf(processor_str, 100, "Core-1 [id:%d,socket:%d]",core_list[0],socket_list[0]); 588 | ProcNames[0]->setText(tr (processor_str)); 589 | snprintf(processor_str, 100, "Core-2 [id:%d,socket:%d]",core_list[1],socket_list[1]); 590 | ProcNames[1]->setText(tr (processor_str)); 591 | snprintf(processor_str, 100, "Core-3 [id:%d,socket:%d]",core_list[2],socket_list[2]); 592 | ProcNames[2]->setText(tr (processor_str)); 593 | snprintf(processor_str, 100, "Core-4 [id:%d,socket:%d]",core_list[3],socket_list[3]); 594 | ProcNames[3]->setText(tr (processor_str)); 595 | snprintf(processor_str, 100, "Core-5 [id:%d,socket:%d]",core_list[4],socket_list[4]); 596 | ProcNames[4]->setText(tr (processor_str)); 597 | snprintf(processor_str, 100, "Core-6 [id:%d,socket:%d]",core_list[5],socket_list[5]); 598 | ProcNames[5]->setText(tr (processor_str)); 599 | snprintf(processor_str, 100, "Core-7 [id:%d,socket:%d]",core_list[6],socket_list[6]); 600 | ProcNames[6]->setText(tr (processor_str)); 601 | snprintf(processor_str, 100, "Core-8 [id:%d,socket:%d]",core_list[7],socket_list[7]); 602 | ProcNames[7]->setText(tr (processor_str)); 603 | snprintf(processor_str, 100, "Core-9 [id:%d,socket:%d]",core_list[8],socket_list[8]); 604 | ProcNames[8]->setText(tr (processor_str)); 605 | snprintf(processor_str, 100, "Core-10 [id:%d,socket:%d]",core_list[9],socket_list[9]); 606 | ProcNames[9]->setText(tr (processor_str)); 607 | snprintf(processor_str, 100, "Core-11 [id:%d,socket:%d]",core_list[10],socket_list[10]); 608 | ProcNames[10]->setText(tr (processor_str)); 609 | snprintf(processor_str, 100, "Core-12 [id:%d,socket:%d]",core_list[11],socket_list[11]); 610 | ProcNames[11]->setText(tr (processor_str)); 611 | 612 | //Have to make sure that the constructor is being called correct. 613 | //the below code logic is that if a core goes offline, call the constructor 614 | //so as to replot all the widgets. 615 | /* printf("Number of Cores %d\n",numCPUs); 616 | if(numCPUs != curr_numCPUs){ 617 | curr_numCPUs = numCPUs; 618 | printf("Number of Cores changed\n"); 619 | MyWidget (0); 620 | }*/ 621 | 622 | // printf("UpdateWidget: Num Processors %d\n",numCPUs); 623 | int i; 624 | char val2set[100]; 625 | for (i = 0; i < (int)numCPUs; i++) 626 | { 627 | snprintf (val2set, 100, "%0.2f Mhz", mythread->FREQ[i]); 628 | Freq_[i]->setText (val2set); 629 | } 630 | 631 | for (i = 0; i < (int)numCPUs; i++) 632 | { 633 | C0_l[i]->setValue (mythread->C0_TIME[i] * 100); 634 | C1_l[i]->setValue (mythread->C1_TIME[i] * 100); 635 | C3_l[i]->setValue (mythread->C3_TIME[i] * 100); 636 | C6_l[i]->setValue (mythread->C6_TIME[i] * 100); 637 | } 638 | 639 | float Max_Freq_socket0 = 0; 640 | float Max_Freq_socket1 = 0; 641 | int num_socket0_cpus, num_socket1_cpus; 642 | 643 | for (i = 0; i < (int)numCPUs; i++) 644 | { 645 | if ( (mythread->FREQ[i] > Max_Freq_socket0) && (!isnan(mythread->FREQ[i])) && 646 | (!isinf(mythread->FREQ[i])) && (socket_list[i] == socket_0.socket_num) ) { 647 | Max_Freq_socket0 = mythread->FREQ[i]; 648 | num_socket0_cpus++; 649 | } 650 | if ( (mythread->FREQ[i] > Max_Freq_socket1) && (!isnan(mythread->FREQ[i])) && 651 | (!isinf(mythread->FREQ[i])) && (socket_list[i] == socket_1.socket_num) ) { 652 | Max_Freq_socket1 = mythread->FREQ[i]; 653 | num_socket1_cpus++; 654 | } 655 | } 656 | if (socket_0.num_physical_cores > 0) { 657 | StatusMessage0->setText ("Socket[0] Freq:"); 658 | snprintf (val2set, 100, "%0.2f Mhz", Max_Freq_socket0); 659 | Curr_Freq0->setText (val2set); 660 | } 661 | if (socket_1.num_physical_cores > 0) { 662 | StatusMessage1->setText ("Socket[1] Freq:"); 663 | snprintf (val2set, 100, "%0.2f Mhz", Max_Freq_socket1); 664 | Curr_Freq1->setText (val2set); 665 | } 666 | } 667 | 668 | 669 | 670 | int 671 | main (int argc, char *argv[]) 672 | { 673 | char hostname[1024]; 674 | hostname[1023] = '\0'; 675 | gethostname(hostname, 1023); 676 | 677 | QApplication app (argc, argv); 678 | 679 | char str_display[1050]; 680 | snprintf(str_display, 1050, "i7z @ %s", hostname); 681 | MyWidget i7z_widget; 682 | i7z_widget.setWindowTitle(str_display); 683 | i7z_widget.show (); 684 | return app.exec (); 685 | } 686 | 687 | #include "i7z_GUI.moc" 688 | --------------------------------------------------------------------------------