Add support for calculating the CPU usage while doing crypto.
This is useful for showing the gains through HW acceleration
other than just speed. It is best used with the '-elapsed' option
to get real-world values.
Currently only linux supports cpu calculations, but it should be easy
to add get_cpu/calc_cpu functions for other OS's.
Also includes a few compile time warning fixes.
Overview : http://www.mail-archive.com/[email protected]/msg26096.html
--
David McCullough, [email protected], Ph:+61 734352815
McAfee - SnapGear http://www.snapgear.com http://www.uCdot.org
diff --git a/apps/speed.c b/apps/speed.c
index 52bc481..a4bef32 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -257,6 +257,80 @@ static SIGRETTYPE sig_done(int sig)
#define START 0
#define STOP 1
+#ifdef __linux__
+
+#define HAVE_CPU_USAGE 1
+
+/*
+ * record CPU usage as well
+ */
+
+struct cpu_stat {
+ unsigned int user;
+ unsigned int nice;
+ unsigned int system;
+ unsigned int idle;
+ unsigned int total;
+};
+
+static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM];
+static unsigned int rsa_cpu_usage[RSA_NUM][2];
+static unsigned int dsa_cpu_usage[DSA_NUM][2];
+static struct cpu_stat cpu_start, cpu_finish;
+
+static void
+get_cpu(int s)
+{
+ FILE *fp = NULL;
+ unsigned char buf[80];
+ struct cpu_stat *st = s == START ? &cpu_start : &cpu_finish;
+
+ memset(st, 0, sizeof(*st));
+
+ if (fp == NULL)
+ fp = fopen("/proc/stat", "r");
+ if (!fp)
+ return;
+ if (fseek(fp, 0, SEEK_SET) == -1) {
+ fclose(fp);
+ return;
+ }
+ if (fscanf(fp, "%s %d %d %d %d", &buf[0], &st->user, &st->nice,
+ &st->system, &st->idle) == 5)
+ st->total = st->user + st->nice + st->system + st->idle;
+ fclose(fp);
+}
+
+static unsigned int
+calc_cpu()
+{
+ unsigned int total, res;
+
+ total = cpu_finish.total - cpu_start.total;
+ if (total <= 0)
+ return 0;
+#if 1 // busy
+ res = ((cpu_finish.system + cpu_finish.user + cpu_finish.nice) -
+ (cpu_start.system + cpu_start.user + cpu_start.nice)) *
+ 100 / total;
+#endif
+#if 0 // system
+ res = (cpu_finish.system - cpu_start.system) * 100 / total;
+#endif
+#if 0 // user
+ res = (cpu_finish.user - cpu_start.user) * 100 / total;
+#endif
+#if 0 // nice
+ res = (cpu_finish.nice - cpu_start.nice) * 100 / total;
+#endif
+#if 0 // idle
+ res = (cpu_finish.idle - cpu_start.idle) * 100 / total;
+#endif
+ return(res);
+}
+
+#endif
+
#if defined(_WIN32)
#define SIGALRM
@@ -273,6 +347,9 @@ static DWORD WINAPI sleepy(VOID *arg)
static double Time_F(int s)
{
+ if (do_cpu)
+ get_cpu(s);
+
if (s == START)
{
HANDLE thr;
@@ -294,6 +371,8 @@ static double Time_F(int s)
static double Time_F(int s)
{
+ if (do_cpu)
+ get_cpu(s);
return app_tminterval(s,usertime);
}
#endif
@@ -316,6 +395,14 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
#endif /* OPENSSL_NO_ECDH */
+static int do_cpu = 0;
+#ifndef HAVE_CPU_USAGE
+/* stub out the cpu functions if we do not support it */
+static void get_cpu(int s) {}
+static unsigned int calc_cpu() { return 0; }
+#endif
+
+
int MAIN(int, char **);
int MAIN(int argc, char **argv)
@@ -670,6 +757,14 @@ int MAIN(int argc, char **argv)
j--; /* Otherwise, -elapsed gets confused with
an algorithm. */
}
+#ifdef HAVE_CPU_USAGE
+ else if ((argc > 0) && (strcmp(*argv,"-cpu") == 0))
+ {
+ do_cpu = 1;
+ j--; /* Otherwise, -cpu gets confused with
+ an algorithm. */
+ }
+#endif
else if ((argc > 0) && (strcmp(*argv,"-evp") == 0))
{
argc--;
@@ -1106,6 +1201,9 @@ int MAIN(int argc, char **argv)
#ifdef HAVE_FORK
BIO_printf(bio_err,"-multi n run n benchmarks in parallel.\n");
#endif
+#ifdef HAVE_CPU_USAGE
+ BIO_printf(bio_err,"-cpu calculate cpu utilisation.\n");
+#endif
goto end;
}
argc--;
@@ -1113,11 +1211,6 @@ int MAIN(int argc, char **argv)
j++;
}
-#ifdef HAVE_FORK
- if(multi && do_multi(multi))
- goto show_res;
-#endif
-
if (j == 0)
{
for (i=0; i<ALGOR_NUM; i++)
@@ -1457,6 +1550,11 @@ int MAIN(int argc, char **argv)
#endif
#endif /* SIGALRM */
+#ifdef HAVE_FORK /* Do this as late as possible to give better CPU readings */
+ if(multi && do_multi(multi))
+ goto show_res;
+#endif
+
#ifndef OPENSSL_NO_MD2
if (doit[D_MD2])
{
@@ -1903,8 +2001,6 @@ int MAIN(int argc, char **argv)
/* -O3 -fschedule-insns messes up an
* optimization here! names[D_EVP]
* somehow becomes NULL */
- print_message(names[D_EVP],save_count,
- lengths[j]);
EVP_CIPHER_CTX_init(&ctx);
if(decrypt)
@@ -1913,6 +2009,9 @@ int MAIN(int argc, char **argv)
EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
+ print_message(names[D_EVP],save_count,
+ lengths[j]);
+
Time_F(START);
if(decrypt)
for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
@@ -1977,6 +2076,8 @@ int MAIN(int argc, char **argv)
}
}
d=Time_F(STOP);
+ if (do_cpu)
+ rsa_cpu_usage[j][0] = calc_cpu();
BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
: "%ld %d bit private RSA's in %.2fs\n",
count,rsa_bits[j],d);
@@ -2012,6 +2113,8 @@ int MAIN(int argc, char **argv)
}
}
d=Time_F(STOP);
+ if (do_cpu)
+ rsa_cpu_usage[j][1] = calc_cpu();
BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
: "%ld %d bit public RSA's in %.2fs\n",
count,rsa_bits[j],d);
@@ -2071,6 +2174,8 @@ int MAIN(int argc, char **argv)
}
}
d=Time_F(STOP);
+ if (do_cpu)
+ dsa_cpu_usage[j][0] = calc_cpu();
BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
: "%ld %d bit DSA signs in %.2fs\n",
count,dsa_bits[j],d);
@@ -2106,6 +2211,8 @@ int MAIN(int argc, char **argv)
}
}
d=Time_F(STOP);
+ if (do_cpu)
+ dsa_cpu_usage[j][1] = calc_cpu();
BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
: "%ld %d bit DSA verify in %.2fs\n",
count,dsa_bits[j],d);
@@ -2371,14 +2478,23 @@ show_res:
fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n");
fprintf(stdout,"type ");
}
- for (j=0; j<SIZE_NUM; j++)
+ for (j=0; j<SIZE_NUM; j++) {
fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
+ if (do_cpu && !mr)
+ fprintf(stdout, " /cpu");
+ }
fprintf(stdout,"\n");
}
for (k=0; k<ALGOR_NUM; k++)
{
if (!doit[k]) continue;
+ if (k == D_EVP) {
+ if (evp_cipher)
+ names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
+ else
+ names[D_EVP]=OBJ_nid2ln(evp_md->type);
+ }
if(mr)
fprintf(stdout,"+F:%d:%s",k,names[k]);
else
@@ -2389,6 +2505,8 @@ show_res:
fprintf(stdout," %11.2fk",results[k][j]/1e3);
else
fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]);
+ if (do_cpu)
+ fprintf(stdout, mr ? "/%d" : "/%%%-3d", cpu_usage[k][j]);
}
fprintf(stdout,"\n");
}
@@ -2403,13 +2521,18 @@ show_res:
j=0;
}
if(mr)
- fprintf(stdout,"+F2:%u:%u:%f:%f\n",
- k,rsa_bits[k],rsa_results[k][0],
- rsa_results[k][1]);
+ fprintf(stdout,"+F2:%u:%u:%f", k,rsa_bits[k],rsa_results[k][0]);
else
- fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
- rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
- 1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+ fprintf(stdout,"rsa %4u bits %8.6fs",rsa_bits[k],rsa_results[k][0]);
+ if (do_cpu)
+ fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][0]);
+ fprintf(stdout, mr ? ":%f" : " %8.6fs", rsa_results[k][1]);
+ if (do_cpu)
+ fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][1]);
+ if(!mr)
+ fprintf(stdout, " %8.1f %8.1f",
+ 1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+ fprintf(stdout, "\n");
}
#endif
#ifndef OPENSSL_NO_DSA
@@ -2423,12 +2546,18 @@ show_res:
j=0;
}
if(mr)
- fprintf(stdout,"+F3:%u:%u:%f:%f\n",
- k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
+ fprintf(stdout,"+F3:%u:%u:%f", k,dsa_bits[k],dsa_results[k][0]);
else
- fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
- dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
- 1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+ fprintf(stdout,"dsa %4u bits %8.6fs",dsa_bits[k],dsa_results[k][0]);
+ if (do_cpu)
+ fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][0]);
+ fprintf(stdout, mr ? ":%f" : " %8.6fs", dsa_results[k][1]);
+ if (do_cpu)
+ fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][1]);
+ if(!mr)
+ fprintf(stdout, " %8.1f %8.1f",
+ 1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+ fprintf(stdout, "\n");
}
#endif
#ifndef OPENSSL_NO_ECDSA
@@ -2553,8 +2682,10 @@ static void pkey_print_message(const char *str, const char *str2, long num,
static void print_result(int alg,int run_no,int count,double time_used)
{
+ if (do_cpu)
+ cpu_usage[alg][run_no] = calc_cpu();
BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
- : "%d %s's in %.2fs\n",count,names[alg],time_used);
+ : "%d %s's in %.2fs\n",count,names[alg],time_used);
results[alg][run_no]=((double)count)/time_used*lengths[run_no];
}
@@ -2600,7 +2731,10 @@ static int do_multi(int multi)
fds=malloc(multi*sizeof *fds);
for(n=0 ; n < multi ; ++n)
{
- pipe(fd);
+ if (pipe(fd) == -1) {
+ fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
+ continue;
+ }
fflush(stdout);
fflush(stderr);
if(fork())
@@ -2612,7 +2746,8 @@ static int do_multi(int multi)
{
close(fd[0]);
close(1);
- dup(fd[1]);
+ if (dup(fd[1]) == -1)
+ fprintf(stderr, "dup() failed: %s\n", strerror(errno));
close(fd[1]);
mr=1;
usertime=0;
@@ -2650,29 +2785,11 @@ static int do_multi(int multi)
p=buf+3;
alg=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
- for(j=0 ; j < SIZE_NUM ; ++j)
+ for(j=0 ; j < SIZE_NUM ; ++j) {
+ if (do_cpu && strchr(p, '/'))
+ cpu_usage[alg][j] = atoi(strchr(p, '/') + 1);
results[alg][j]+=atof(sstrsep(&p,sep));
}
- else if(!strncmp(buf,"+F2:",4))
- {
- int k;
- double d;
-
- p=buf+4;
- k=atoi(sstrsep(&p,sep));
- sstrsep(&p,sep);
-
- d=atof(sstrsep(&p,sep));
- if(n)
- rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
- else
- rsa_results[k][0]=d;
-
- d=atof(sstrsep(&p,sep));
- if(n)
- rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
- else
- rsa_results[k][1]=d;
}
else if(!strncmp(buf,"+F2:",4))
{
@@ -2683,12 +2800,18 @@ static int do_multi(int multi)
k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
+ /* before we move the token along */
+ if (do_cpu && strchr(p, '/'))
+ rsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1);
d=atof(sstrsep(&p,sep));
if(n)
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
else
rsa_results[k][0]=d;
+ /* before we move the token along */
+ if (do_cpu && strchr(p, '/'))
+ rsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1);
d=atof(sstrsep(&p,sep));
if(n)
rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
@@ -2704,12 +2827,18 @@ static int do_multi(int multi)
k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
+ /* before we move the token along */
+ if (do_cpu && strchr(p, '/'))
+ dsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1);
d=atof(sstrsep(&p,sep));
if(n)
dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
else
dsa_results[k][0]=d;
+ /* before we move the token along */
+ if (do_cpu && strchr(p, '/'))
+ dsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1);
d=atof(sstrsep(&p,sep));
if(n)
dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
diff --git a/apps/speed.c b/apps/speed.c
index a4bef32..c6f5b0e 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -277,6 +277,7 @@ static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM];
static unsigned int rsa_cpu_usage[RSA_NUM][2];
static unsigned int dsa_cpu_usage[DSA_NUM][2];
static struct cpu_stat cpu_start, cpu_finish;
+static int do_cpu = 0;
static void
get_cpu(int s)
@@ -395,7 +396,6 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
#endif /* OPENSSL_NO_ECDH */
-static int do_cpu = 0;
#ifndef HAVE_CPU_USAGE
/* stub out the cpu functions if we do not support it */
static void get_cpu(int s) {}
--
1.6.0.4