diff --git a/src/arm/midr.c b/src/arm/midr.c index c5531df..a4ad6b3 100644 --- a/src/arm/midr.c +++ b/src/arm/midr.c @@ -15,6 +15,7 @@ #include "../common/global.h" #include "../common/soc.h" +#include "../common/args.h" #include "udev.h" #include "midr.h" #include "uarch.h" @@ -44,8 +45,9 @@ struct frequency* get_frequency_info(uint32_t core) { freq->base = UNKNOWN_DATA; freq->max = get_max_freq_from_file(core); #ifdef __linux__ - if (freq->max == UNKNOWN_DATA) { - printWarn("Unable to find max frequency from udev, measuring CPU frequency"); + if (freq->max == UNKNOWN_DATA || measure_max_frequency_flag()) { + if (freq->max == UNKNOWN_DATA) + printWarn("Unable to find max frequency from udev, measuring CPU frequency"); freq->max = measure_max_frequency(core); freq->measured = true; } diff --git a/src/common/args.c b/src/common/args.c index b3d2b10..719cd7c 100644 --- a/src/common/args.c +++ b/src/common/args.c @@ -28,6 +28,7 @@ struct args_struct { bool help_flag; bool raw_flag; bool accurate_pp; + bool measure_max_frequency_flag; bool full_cpu_name_flag; bool logo_long; bool logo_short; @@ -40,35 +41,37 @@ struct args_struct { }; const char args_chr[] = { - /* [ARG_STYLE] = */ 's', - /* [ARG_COLOR] = */ 'c', - /* [ARG_HELP] = */ 'h', - /* [ARG_RAW] = */ 'r', - /* [ARG_FULLCPUNAME] = */ 'F', - /* [ARG_LOGO_LONG] = */ 1, - /* [ARG_LOGO_SHORT] = */ 2, - /* [ARG_LOGO_INTEL_NEW] = */ 3, - /* [ARG_LOGO_INTEL_OLD] = */ 4, - /* [ARG_ACCURATE_PP] = */ 5, - /* [ARG_DEBUG] = */ 'd', - /* [ARG_VERBOSE] = */ 'v', - /* [ARG_VERSION] = */ 'V', + /* [ARG_STYLE] = */ 's', + /* [ARG_COLOR] = */ 'c', + /* [ARG_HELP] = */ 'h', + /* [ARG_RAW] = */ 'r', + /* [ARG_FULLCPUNAME] = */ 'F', + /* [ARG_LOGO_LONG] = */ 1, + /* [ARG_LOGO_SHORT] = */ 2, + /* [ARG_LOGO_INTEL_NEW] = */ 3, + /* [ARG_LOGO_INTEL_OLD] = */ 4, + /* [ARG_ACCURATE_PP] = */ 5, + /* [ARG_MEASURE_MAX_FREQ] = */ 6, + /* [ARG_DEBUG] = */ 'd', + /* [ARG_VERBOSE] = */ 'v', + /* [ARG_VERSION] = */ 'V', }; const char *args_str[] = { - /* [ARG_STYLE] = */ "style", - /* [ARG_COLOR] = */ "color", - /* [ARG_HELP] = */ "help", - /* [ARG_RAW] = */ "raw", - /* [ARG_FULLCPUNAME] = */ "full-cpu-name", - /* [ARG_LOGO_LONG] = */ "logo-long", - /* [ARG_LOGO_SHORT] = */ "logo-short", - /* [ARG_LOGO_INTEL_NEW] = */ "logo-intel-new", - /* [ARG_LOGO_INTEL_OLD] = */ "logo-intel-old", - /* [ARG_ACCURATE_PP] = */ "accurate-pp", - /* [ARG_DEBUG] = */ "debug", - /* [ARG_VERBOSE] = */ "verbose", - /* [ARG_VERSION] = */ "version", + /* [ARG_STYLE] = */ "style", + /* [ARG_COLOR] = */ "color", + /* [ARG_HELP] = */ "help", + /* [ARG_RAW] = */ "raw", + /* [ARG_FULLCPUNAME] = */ "full-cpu-name", + /* [ARG_LOGO_LONG] = */ "logo-long", + /* [ARG_LOGO_SHORT] = */ "logo-short", + /* [ARG_LOGO_INTEL_NEW] = */ "logo-intel-new", + /* [ARG_LOGO_INTEL_OLD] = */ "logo-intel-old", + /* [ARG_ACCURATE_PP] = */ "accurate-pp", + /* [ARG_MEASURE_MAX_FREQ] = */ "measure-max-freq", + /* [ARG_DEBUG] = */ "debug", + /* [ARG_VERBOSE] = */ "verbose", + /* [ARG_VERSION] = */ "version", }; static struct args_struct args; @@ -101,6 +104,10 @@ bool accurate_pp(void) { return args.accurate_pp; } +bool measure_max_frequency_flag(void) { + return args.measure_max_frequency_flag; +} + bool show_full_cpu_name(void) { return args.full_cpu_name_flag; } @@ -222,12 +229,20 @@ char* build_short_options(void) { memset(str, 0, sizeof(char) * (len*2 + 1)); #ifdef ARCH_X86 - sprintf(str, "%c:%c:%c%c%c%c%c%c%c%c%c%c%c", + sprintf(str, "%c:%c:%c%c%c%c%c%c%c%c%c%c%c%c", c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP], c[ARG_RAW], c[ARG_FULLCPUNAME], c[ARG_LOGO_SHORT], c[ARG_LOGO_LONG], c[ARG_LOGO_INTEL_NEW], c[ARG_LOGO_INTEL_OLD], - c[ARG_ACCURATE_PP], c[ARG_DEBUG], c[ARG_VERBOSE], + c[ARG_ACCURATE_PP], c[ARG_MEASURE_MAX_FREQ], + c[ARG_DEBUG], c[ARG_VERBOSE], + c[ARG_VERSION]); +#elif ARCH_ARM + sprintf(str, "%c:%c:%c%c%c%c%c%c%c", + c[ARG_STYLE], c[ARG_COLOR], c[ARG_HELP], + c[ARG_LOGO_SHORT], c[ARG_LOGO_LONG], + c[ARG_MEASURE_MAX_FREQ], + c[ARG_DEBUG], c[ARG_VERBOSE], c[ARG_VERSION]); #else sprintf(str, "%c:%c:%c%c%c%c%c%c", @@ -263,21 +278,24 @@ bool parse_args(int argc, char* argv[]) { set_log_level(true); const struct option long_options[] = { - {args_str[ARG_STYLE], required_argument, 0, args_chr[ARG_STYLE] }, - {args_str[ARG_COLOR], required_argument, 0, args_chr[ARG_COLOR] }, - {args_str[ARG_HELP], no_argument, 0, args_chr[ARG_HELP] }, + {args_str[ARG_STYLE], required_argument, 0, args_chr[ARG_STYLE] }, + {args_str[ARG_COLOR], required_argument, 0, args_chr[ARG_COLOR] }, + {args_str[ARG_HELP], no_argument, 0, args_chr[ARG_HELP] }, #ifdef ARCH_X86 - {args_str[ARG_LOGO_INTEL_NEW], no_argument, 0, args_chr[ARG_LOGO_INTEL_NEW] }, - {args_str[ARG_LOGO_INTEL_OLD], no_argument, 0, args_chr[ARG_LOGO_INTEL_OLD] }, - {args_str[ARG_ACCURATE_PP], no_argument, 0, args_chr[ARG_ACCURATE_PP] }, - {args_str[ARG_FULLCPUNAME], no_argument, 0, args_chr[ARG_FULLCPUNAME] }, - {args_str[ARG_RAW], no_argument, 0, args_chr[ARG_RAW] }, + {args_str[ARG_LOGO_INTEL_NEW], no_argument, 0, args_chr[ARG_LOGO_INTEL_NEW] }, + {args_str[ARG_LOGO_INTEL_OLD], no_argument, 0, args_chr[ARG_LOGO_INTEL_OLD] }, + {args_str[ARG_ACCURATE_PP], no_argument, 0, args_chr[ARG_ACCURATE_PP] }, + {args_str[ARG_MEASURE_MAX_FREQ], no_argument, 0, args_chr[ARG_MEASURE_MAX_FREQ] }, + {args_str[ARG_FULLCPUNAME], no_argument, 0, args_chr[ARG_FULLCPUNAME] }, + {args_str[ARG_RAW], no_argument, 0, args_chr[ARG_RAW] }, +#elif ARCH_ARM + {args_str[ARG_MEASURE_MAX_FREQ], no_argument, 0, args_chr[ARG_MEASURE_MAX_FREQ] }, #endif - {args_str[ARG_LOGO_SHORT], no_argument, 0, args_chr[ARG_LOGO_SHORT] }, - {args_str[ARG_LOGO_LONG], no_argument, 0, args_chr[ARG_LOGO_LONG] }, - {args_str[ARG_DEBUG], no_argument, 0, args_chr[ARG_DEBUG] }, - {args_str[ARG_VERBOSE], no_argument, 0, args_chr[ARG_VERBOSE] }, - {args_str[ARG_VERSION], no_argument, 0, args_chr[ARG_VERSION] }, + {args_str[ARG_LOGO_SHORT], no_argument, 0, args_chr[ARG_LOGO_SHORT] }, + {args_str[ARG_LOGO_LONG], no_argument, 0, args_chr[ARG_LOGO_LONG] }, + {args_str[ARG_DEBUG], no_argument, 0, args_chr[ARG_DEBUG] }, + {args_str[ARG_VERBOSE], no_argument, 0, args_chr[ARG_VERBOSE] }, + {args_str[ARG_VERSION], no_argument, 0, args_chr[ARG_VERSION] }, {0, 0, 0, 0} }; @@ -313,6 +331,9 @@ bool parse_args(int argc, char* argv[]) { else if(opt == args_chr[ARG_ACCURATE_PP]) { args.accurate_pp = true; } + else if(opt == args_chr[ARG_MEASURE_MAX_FREQ]) { + args.measure_max_frequency_flag = true; + } else if(opt == args_chr[ARG_FULLCPUNAME]) { args.full_cpu_name_flag = true; } diff --git a/src/common/args.h b/src/common/args.h index 116c178..a81380b 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -29,6 +29,7 @@ enum { ARG_LOGO_INTEL_NEW, ARG_LOGO_INTEL_OLD, ARG_ACCURATE_PP, + ARG_MEASURE_MAX_FREQ, ARG_DEBUG, ARG_VERBOSE, ARG_VERSION @@ -43,6 +44,7 @@ int max_arg_str_length(void); bool parse_args(int argc, char* argv[]); bool show_help(void); bool accurate_pp(void); +bool measure_max_frequency_flag(void); bool show_full_cpu_name(void); bool show_logo_long(void); bool show_logo_short(void); diff --git a/src/common/main.c b/src/common/main.c index 4b1fbd0..f26e9aa 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -30,11 +30,17 @@ void print_help(char *argv[]) { #ifdef ARCH_X86 #ifdef __linux__ printf(" --%s %*s Compute the peak performance accurately (measure the CPU frequency instead of using the maximum)\n", t[ARG_ACCURATE_PP], (int) (max_len-strlen(t[ARG_ACCURATE_PP])), ""); -#endif + printf(" --%s %*s Measure the max CPU frequency instead of reading it\n", t[ARG_MEASURE_MAX_FREQ], (int) (max_len-strlen(t[ARG_MEASURE_MAX_FREQ])), ""); +#endif // __linux__ printf(" --%s %*s Show the old Intel logo\n", t[ARG_LOGO_INTEL_OLD], (int) (max_len-strlen(t[ARG_LOGO_INTEL_OLD])), ""); printf(" --%s %*s Show the new Intel logo\n", t[ARG_LOGO_INTEL_NEW], (int) (max_len-strlen(t[ARG_LOGO_INTEL_NEW])), ""); printf(" -%c, --%s %*s Show the full CPU name (do not abbreviate it)\n", c[ARG_FULLCPUNAME], t[ARG_FULLCPUNAME], (int) (max_len-strlen(t[ARG_FULLCPUNAME])), ""); printf(" -%c, --%s %*s Print raw cpuid data (debug purposes)\n", c[ARG_RAW], t[ARG_RAW], (int) (max_len-strlen(t[ARG_RAW])), ""); +#endif // ARCH_X86 +#ifdef ARCH_ARM +#ifdef __linux__ + printf(" --%s %*s Measure the max CPU frequency instead of reading it\n", t[ARG_MEASURE_MAX_FREQ], (int) (max_len-strlen(t[ARG_MEASURE_MAX_FREQ])), ""); +#endif #endif printf(" -%c, --%s %*s Print this help and exit\n", c[ARG_HELP], t[ARG_HELP], (int) (max_len-strlen(t[ARG_HELP])), ""); printf(" -%c, --%s %*s Print cpufetch version and exit\n", c[ARG_VERSION], t[ARG_VERSION], (int) (max_len-strlen(t[ARG_VERSION])), ""); @@ -80,6 +86,11 @@ void print_help(char *argv[]) { printf(" --accurate-pp option, which will measure the AVX frequency and show a more precise estimation\n"); printf(" (this option is only available in x86 architectures).\n"); printf(" To precisely measure peak performance, see: https://github.com/Dr-Noob/peakperf\n"); + printf("\n"); + printf(" Both --accurate-pp and --measure-max-freq measure the actual frequency of the CPU. However,\n"); + printf(" they differ slightly. The former measures the max frequency while running vectorized SSE/AVX\n"); + printf(" instructions and it is thus x86 only, whereas the latter simply measures the max clock cycle\n"); + printf(" and is architecture independent.\n"); } int main(int argc, char* argv[]) { diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 84821d6..eb06d9a 100644 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -973,8 +973,9 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) { } #ifdef __linux__ - if (freq->max == UNKNOWN_DATA) { - printWarn("All previous methods failed, measuring CPU frequency"); + if (freq->max == UNKNOWN_DATA || measure_max_frequency_flag()) { + if (freq->max == UNKNOWN_DATA) + printWarn("All previous methods failed, measuring CPU frequency"); // TODO: Support hybrid architectures freq->max = measure_max_frequency(0); freq->measured = true;