Message ID | 1355227446-14380-2-git-send-email-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On Tue, Dec 11, 2012 at 8:04 PM, Colin King <colin.king@canonical.com> wrote: > From: Colin Ian King <colin.king@canonical.com> > > The C-states and CPU frequency tests use fairly common code to load > the CPUs. Move this into fwts_cpu.c as fwts_cpu_performance() which > measures the performance of a specified CPU for just 1 second and > returns a bogo metric of CPU performance. Also add in a CPU load > helper function. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts_cpu.h | 3 ++ > src/lib/src/fwts_cpu.c | 98 +++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 95 insertions(+), 6 deletions(-) > > diff --git a/src/lib/include/fwts_cpu.h b/src/lib/include/fwts_cpu.h > index a90141d..daf48a2 100644 > --- a/src/lib/include/fwts_cpu.h > +++ b/src/lib/include/fwts_cpu.h > @@ -20,6 +20,8 @@ > #ifndef __FWTS_CPU_H__ > #define __FWTS_CPU_H__ > > +#include "fwts_framework.h" > + > #include <stdbool.h> > > typedef struct cpuinfo_x86 { > @@ -44,5 +46,6 @@ int fwts_cpu_enumerate(void); > int fwts_cpu_consume(const int seconds); > int fwts_cpu_consume_start(void); > void fwts_cpu_consume_complete(void); > +int fwts_cpu_performance(fwts_framework *fw, const int cpu, uint64_t *loop_count); > > #endif > diff --git a/src/lib/src/fwts_cpu.c b/src/lib/src/fwts_cpu.c > index 80d7824..91cb87e 100644 > --- a/src/lib/src/fwts_cpu.c > +++ b/src/lib/src/fwts_cpu.c > @@ -31,6 +31,9 @@ > #include <sys/wait.h> > #include <signal.h> > #include <fcntl.h> > +#include <math.h> > +#include <sched.h> > +#include <time.h> > > #include "fwts_types.h" > #include "fwts_cpu.h" > @@ -287,6 +290,92 @@ static void fwts_cpu_sigint_handler(int dummy) > _exit(0); > } > > + > +/* > + * fwts_cpu_burn_cycles() > + * burn some CPU cycles > + */ > +static void fwts_cpu_burn_cycles(void) > +{ > + double A = 1.234567; > + double B = 3.121213; > + int i; > + > + for (i = 0; i < 100; i++) { > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + } > +} > + > +/* > + * fwts_cpu_performance() > + * > + */ > +int fwts_cpu_performance( > + fwts_framework *fw, > + const int cpu, /* CPU we want to measure performance */ > + uint64_t *loop_count) /* Returned measure of bogo compute power */ > +{ > + cpu_set_t mask, oldset; > + time_t current; > + int ncpus = fwts_cpu_enumerate(); > + > + *loop_count = 0; > + > + if (ncpus == FWTS_ERROR) > + return FWTS_ERROR; > + > + if (cpu < 0 || cpu > ncpus) > + return FWTS_ERROR; > + > + /* Pin to the specified CPU */ > + > + if (sched_getaffinity(0, sizeof(oldset), &oldset) < 0) { > + fwts_log_error(fw, "Cannot get scheduling affinity."); > + return FWTS_ERROR; > + } > + > + CPU_ZERO(&mask); > + CPU_SET(cpu, &mask); > + if (sched_setaffinity(0, sizeof(mask), &mask) < 0) { > + fwts_log_error(fw, "Cannot set scheduling affinity to CPU %d.", cpu); > + return FWTS_ERROR; > + } > + > + /* Wait until we get a new second */ > + current = time(NULL); > + while (current == time(NULL)) > + sched_yield(); > + > + current = time(NULL); > + > + /* > + * And burn some CPU cycles and get a bogo-compute like > + * loop count measure of CPU performance. > + */ > + do { > + fwts_cpu_burn_cycles(); > + (*loop_count)++; > + } while (current == time(NULL)); > + > + if (sched_setaffinity(0, sizeof(oldset), &oldset) < 0) { > + fwts_log_error(fw, "Cannot restore old CPU affinity settings."); > + return FWTS_ERROR; > + } > + > + return FWTS_OK; > +} > + > /* > * fwts_cpu_consume_cycles() > * eat up CPU cycles > @@ -294,17 +383,14 @@ static void fwts_cpu_sigint_handler(int dummy) > static void fwts_cpu_consume_cycles(void) > { > signal(SIGUSR1, fwts_cpu_consume_sighandler); > + uint64_t i; > > - float dummy = 0.000001; > - unsigned long long i = 0; > - > - while (dummy > 0.0) { > - dummy += 0.0000037; > + for (;;) { > + fwts_cpu_burn_cycles(); > i++; > } > } > > - > /* > * fwts_cpu_consume_complete() > * kill all CPU consumes, free up pid info > -- > 1.8.0 > Acked-by: Keng-Yu Lin <kengyu@canonical.com>
On 12/11/2012 08:04 PM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > The C-states and CPU frequency tests use fairly common code to load > the CPUs. Move this into fwts_cpu.c as fwts_cpu_performance() which > measures the performance of a specified CPU for just 1 second and > returns a bogo metric of CPU performance. Also add in a CPU load > helper function. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts_cpu.h | 3 ++ > src/lib/src/fwts_cpu.c | 98 +++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 95 insertions(+), 6 deletions(-) > > diff --git a/src/lib/include/fwts_cpu.h b/src/lib/include/fwts_cpu.h > index a90141d..daf48a2 100644 > --- a/src/lib/include/fwts_cpu.h > +++ b/src/lib/include/fwts_cpu.h > @@ -20,6 +20,8 @@ > #ifndef __FWTS_CPU_H__ > #define __FWTS_CPU_H__ > > +#include "fwts_framework.h" > + > #include <stdbool.h> > > typedef struct cpuinfo_x86 { > @@ -44,5 +46,6 @@ int fwts_cpu_enumerate(void); > int fwts_cpu_consume(const int seconds); > int fwts_cpu_consume_start(void); > void fwts_cpu_consume_complete(void); > +int fwts_cpu_performance(fwts_framework *fw, const int cpu, uint64_t *loop_count); > > #endif > diff --git a/src/lib/src/fwts_cpu.c b/src/lib/src/fwts_cpu.c > index 80d7824..91cb87e 100644 > --- a/src/lib/src/fwts_cpu.c > +++ b/src/lib/src/fwts_cpu.c > @@ -31,6 +31,9 @@ > #include <sys/wait.h> > #include <signal.h> > #include <fcntl.h> > +#include <math.h> > +#include <sched.h> > +#include <time.h> > > #include "fwts_types.h" > #include "fwts_cpu.h" > @@ -287,6 +290,92 @@ static void fwts_cpu_sigint_handler(int dummy) > _exit(0); > } > > + > +/* > + * fwts_cpu_burn_cycles() > + * burn some CPU cycles > + */ > +static void fwts_cpu_burn_cycles(void) > +{ > + double A = 1.234567; > + double B = 3.121213; > + int i; > + > + for (i = 0; i < 100; i++) { > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + A = A * B; > + B = A * A; > + A = A - B + sqrt(A); > + } > +} > + > +/* > + * fwts_cpu_performance() > + * > + */ > +int fwts_cpu_performance( > + fwts_framework *fw, > + const int cpu, /* CPU we want to measure performance */ > + uint64_t *loop_count) /* Returned measure of bogo compute power */ > +{ > + cpu_set_t mask, oldset; > + time_t current; > + int ncpus = fwts_cpu_enumerate(); > + > + *loop_count = 0; > + > + if (ncpus == FWTS_ERROR) > + return FWTS_ERROR; > + > + if (cpu < 0 || cpu > ncpus) > + return FWTS_ERROR; > + > + /* Pin to the specified CPU */ > + > + if (sched_getaffinity(0, sizeof(oldset), &oldset) < 0) { > + fwts_log_error(fw, "Cannot get scheduling affinity."); > + return FWTS_ERROR; > + } > + > + CPU_ZERO(&mask); > + CPU_SET(cpu, &mask); > + if (sched_setaffinity(0, sizeof(mask), &mask) < 0) { > + fwts_log_error(fw, "Cannot set scheduling affinity to CPU %d.", cpu); > + return FWTS_ERROR; > + } > + > + /* Wait until we get a new second */ > + current = time(NULL); > + while (current == time(NULL)) > + sched_yield(); > + > + current = time(NULL); > + > + /* > + * And burn some CPU cycles and get a bogo-compute like > + * loop count measure of CPU performance. > + */ > + do { > + fwts_cpu_burn_cycles(); > + (*loop_count)++; > + } while (current == time(NULL)); > + > + if (sched_setaffinity(0, sizeof(oldset), &oldset) < 0) { > + fwts_log_error(fw, "Cannot restore old CPU affinity settings."); > + return FWTS_ERROR; > + } > + > + return FWTS_OK; > +} > + > /* > * fwts_cpu_consume_cycles() > * eat up CPU cycles > @@ -294,17 +383,14 @@ static void fwts_cpu_sigint_handler(int dummy) > static void fwts_cpu_consume_cycles(void) > { > signal(SIGUSR1, fwts_cpu_consume_sighandler); > + uint64_t i; > > - float dummy = 0.000001; > - unsigned long long i = 0; > - > - while (dummy > 0.0) { > - dummy += 0.0000037; > + for (;;) { > + fwts_cpu_burn_cycles(); > i++; > } > } > > - > /* > * fwts_cpu_consume_complete() > * kill all CPU consumes, free up pid info > Acked-by: Ivan Hu <ivan.hu@canonical.com>
diff --git a/src/lib/include/fwts_cpu.h b/src/lib/include/fwts_cpu.h index a90141d..daf48a2 100644 --- a/src/lib/include/fwts_cpu.h +++ b/src/lib/include/fwts_cpu.h @@ -20,6 +20,8 @@ #ifndef __FWTS_CPU_H__ #define __FWTS_CPU_H__ +#include "fwts_framework.h" + #include <stdbool.h> typedef struct cpuinfo_x86 { @@ -44,5 +46,6 @@ int fwts_cpu_enumerate(void); int fwts_cpu_consume(const int seconds); int fwts_cpu_consume_start(void); void fwts_cpu_consume_complete(void); +int fwts_cpu_performance(fwts_framework *fw, const int cpu, uint64_t *loop_count); #endif diff --git a/src/lib/src/fwts_cpu.c b/src/lib/src/fwts_cpu.c index 80d7824..91cb87e 100644 --- a/src/lib/src/fwts_cpu.c +++ b/src/lib/src/fwts_cpu.c @@ -31,6 +31,9 @@ #include <sys/wait.h> #include <signal.h> #include <fcntl.h> +#include <math.h> +#include <sched.h> +#include <time.h> #include "fwts_types.h" #include "fwts_cpu.h" @@ -287,6 +290,92 @@ static void fwts_cpu_sigint_handler(int dummy) _exit(0); } + +/* + * fwts_cpu_burn_cycles() + * burn some CPU cycles + */ +static void fwts_cpu_burn_cycles(void) +{ + double A = 1.234567; + double B = 3.121213; + int i; + + for (i = 0; i < 100; i++) { + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + } +} + +/* + * fwts_cpu_performance() + * + */ +int fwts_cpu_performance( + fwts_framework *fw, + const int cpu, /* CPU we want to measure performance */ + uint64_t *loop_count) /* Returned measure of bogo compute power */ +{ + cpu_set_t mask, oldset; + time_t current; + int ncpus = fwts_cpu_enumerate(); + + *loop_count = 0; + + if (ncpus == FWTS_ERROR) + return FWTS_ERROR; + + if (cpu < 0 || cpu > ncpus) + return FWTS_ERROR; + + /* Pin to the specified CPU */ + + if (sched_getaffinity(0, sizeof(oldset), &oldset) < 0) { + fwts_log_error(fw, "Cannot get scheduling affinity."); + return FWTS_ERROR; + } + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (sched_setaffinity(0, sizeof(mask), &mask) < 0) { + fwts_log_error(fw, "Cannot set scheduling affinity to CPU %d.", cpu); + return FWTS_ERROR; + } + + /* Wait until we get a new second */ + current = time(NULL); + while (current == time(NULL)) + sched_yield(); + + current = time(NULL); + + /* + * And burn some CPU cycles and get a bogo-compute like + * loop count measure of CPU performance. + */ + do { + fwts_cpu_burn_cycles(); + (*loop_count)++; + } while (current == time(NULL)); + + if (sched_setaffinity(0, sizeof(oldset), &oldset) < 0) { + fwts_log_error(fw, "Cannot restore old CPU affinity settings."); + return FWTS_ERROR; + } + + return FWTS_OK; +} + /* * fwts_cpu_consume_cycles() * eat up CPU cycles @@ -294,17 +383,14 @@ static void fwts_cpu_sigint_handler(int dummy) static void fwts_cpu_consume_cycles(void) { signal(SIGUSR1, fwts_cpu_consume_sighandler); + uint64_t i; - float dummy = 0.000001; - unsigned long long i = 0; - - while (dummy > 0.0) { - dummy += 0.0000037; + for (;;) { + fwts_cpu_burn_cycles(); i++; } } - /* * fwts_cpu_consume_complete() * kill all CPU consumes, free up pid info