Patchwork [1/4] lib: cpu: add common CPU performance measuring code to fwts library

login
register
mail settings
Submitter Colin King
Date Dec. 11, 2012, 12:04 p.m.
Message ID <1355227446-14380-2-git-send-email-colin.king@canonical.com>
Download mbox | patch
Permalink /patch/205189/
State Accepted
Headers show

Comments

Colin King - Dec. 11, 2012, 12:04 p.m.
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(-)
Keng-Yu Lin - Dec. 18, 2012, 2:22 a.m.
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>
Ivan Hu - Dec. 19, 2012, 7:54 a.m.
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>

Patch

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