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/openssl-dev@openssl.org/msg26096.html -- David McCullough, david_mccullo...@securecomputing.com, 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