1 // SPDX-License-Identifier: GPL-2.0 2 #include <math.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <sys/types.h> 7 #include <sys/stat.h> 8 #include <fcntl.h> 9 #include <sys/timeb.h> 10 #include <sched.h> 11 #include <errno.h> 12 13 void usage(char *name) { 14 printf ("Usage: %s cpunum\n", name); 15 } 16 17 int main(int argc, char **argv) { 18 unsigned int i, cpu, fd; 19 char msr_file_name[64]; 20 long long tsc, old_tsc, new_tsc; 21 long long aperf, old_aperf, new_aperf; 22 long long mperf, old_mperf, new_mperf; 23 struct timeb before, after; 24 long long int start, finish, total; 25 cpu_set_t cpuset; 26 27 if (argc != 2) { 28 usage(argv[0]); 29 return 1; 30 } 31 32 errno = 0; 33 cpu = strtol(argv[1], (char **) NULL, 10); 34 35 if (errno) { 36 usage(argv[0]); 37 return 1; 38 } 39 40 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); 41 fd = open(msr_file_name, O_RDONLY); 42 43 if (fd == -1) { 44 perror("Failed to open"); 45 return 1; 46 } 47 48 CPU_ZERO(&cpuset); 49 CPU_SET(cpu, &cpuset); 50 51 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) { 52 perror("Failed to set cpu affinity"); 53 return 1; 54 } 55 56 ftime(&before); 57 pread(fd, &old_tsc, sizeof(old_tsc), 0x10); 58 pread(fd, &old_aperf, sizeof(old_mperf), 0xe7); 59 pread(fd, &old_mperf, sizeof(old_aperf), 0xe8); 60 61 for (i=0; i<0x8fffffff; i++) { 62 sqrt(i); 63 } 64 65 ftime(&after); 66 pread(fd, &new_tsc, sizeof(new_tsc), 0x10); 67 pread(fd, &new_aperf, sizeof(new_mperf), 0xe7); 68 pread(fd, &new_mperf, sizeof(new_aperf), 0xe8); 69 70 tsc = new_tsc-old_tsc; 71 aperf = new_aperf-old_aperf; 72 mperf = new_mperf-old_mperf; 73 74 start = before.time*1000 + before.millitm; 75 finish = after.time*1000 + after.millitm; 76 total = finish - start; 77 78 printf("runTime: %4.2f\n", 1.0*total/1000); 79 printf("freq: %7.0f\n", tsc / (1.0*aperf / (1.0 * mperf)) / total); 80 return 0; 81 } 82