xref: /isa-l_crypto/examples/saturation_test/isal_multithread_perf.c (revision a7753fe3f5e15d45f9d62d8d197b068929dd5f7a)
1 /**
2  * @file isal_multithread_perf.c
3  * @brief It is used to verify high speed algorithm saturation issue
4  * @details
5  *	usage: taskset -c <cpu_index1,cpu_index2,...> isal_multithread_perf -m <algorithm name> -n <thread num>
6  *	eg: taskset -c 0-9,20-29 ./isal_multithread_perf -m md5_mb -n 10
7  */
8 
9 #include <pthread.h>
10 #include <sys/time.h>
11 #include <sys/types.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stdbool.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <stdarg.h>
18 
19 #include "isal_multithread_perf.h"
20 
21 alg_method algs[] = {
22 	{"md5", md5_ossl_func, MD5_MAX_LANES}
23 	,
24 	{"md5_mb", md5_mb_func, MD5_MAX_LANES}
25 	,
26 	{"sha1", sha1_ossl_func, SHA1_MAX_LANES}
27 	,
28 	{"sha1_mb", sha1_mb_func, SHA1_MAX_LANES}
29 	,
30 	{"sha256", sha256_ossl_func, SHA256_MAX_LANES}
31 	,
32 	{"sha256_mb", sha256_mb_func, SHA256_MAX_LANES}
33 	,
34 	{"sha512", sha512_ossl_func, SHA512_MAX_LANES}
35 	,
36 	{"sha512_mb", sha512_mb_func, SHA512_MAX_LANES}
37 	,
38 	{"cbc_128_dec", cbc_128_dec_func, 1}
39 	,
40 	{"cbc_192_dec", cbc_192_dec_func, 1}
41 	,
42 	{"cbc_256_dec", cbc_256_dec_func, 1}
43 	,
44 	{"xts_128_enc", xts_128_enc_func, 1}
45 	,
46 	{"xts_256_enc", xts_256_enc_func, 1}
47 	,
48 	{"gcm_128_enc", gcm_128_enc_func, 1}
49 	,
50 	{"gcm_256_enc", gcm_256_enc_func, 1}
51 	,
52 
53 	{NULL, NULL}
54 };
55 
56 /* Global parameters*/
57 long long run_secs = 10;
58 uint32_t num_threads = 2;
59 uint32_t buflen = 32 * 1024;
60 uint32_t prememcpy = 0;
61 uint32_t postmemcpy = 0;
62 char *method = "md5_mb";
63 
64 /* Global thread sync */
65 pthread_mutex_t count_lock = PTHREAD_MUTEX_INITIALIZER;
66 pthread_cond_t count_cond = PTHREAD_COND_INITIALIZER;
67 volatile uint32_t count = 0;
68 
69 int verbose = 0;
70 
71 void usage(char *appname)
72 {
73 	int i = 0;
74 	printf("Usage: %s -n num_threads\n", appname);
75 	printf("\t-v verbose output\n"
76 	       "\t-t time to run(secs)\n"
77 	       "\t-n number of algorithm threads\n"
78 	       "\t-l len of each buffer(KB)\n"
79 	       "\t-a memory copy before algorithm -- 1 do(default); 0 not do\n"
80 	       "\t-b memory copy after algorithm -- 1 do(default); 0 not do\n"
81 	       "\t-m method of algorithm:");
82 	for (i = 0; algs[i].name != NULL; i++)
83 		printf("  %s", algs[i].name);
84 	printf("\n");
85 
86 }
87 
88 void notice(char *appname, alg_method * alg_choose_p)
89 {
90 	int i = 0;
91 	printf("%s starts to run\n", appname);
92 	printf("\tverbose output is %d\n"
93 	       "\truntime is %lld(secs)\n"
94 	       "\tnumber of algorithm threads is %d\n"
95 	       "\tlen of each buffer(KB) is %d\n"
96 	       "\tmemory copy before algorithm is %d\n"
97 	       "\tmemory copy after algorithm is %d\n"
98 	       "\tmethod of algorithm is %s\n", verbose, run_secs, num_threads, buflen / 1024,
99 	       prememcpy, postmemcpy, alg_choose_p->name);
100 }
101 
102 int main(int argc, char **argv)
103 {
104 	int i = 0;
105 	int opt;
106 	char *optstring = "t:n:m:l:a:b:v";
107 	int32_t *id = NULL, ret = 0;
108 	alg_method alg_choose;
109 	pthread_t *clients = NULL;
110 	uint64_t count = 0, sum = 0;
111 	uint32_t rounds_buf;
112 
113 	while ((opt = getopt(argc, argv, optstring)) != -1) {
114 		switch (opt) {
115 		case 't':
116 			run_secs = atol(optarg);
117 			if (run_secs <= 0) {
118 				usage(argv[0]);
119 				exit(-1);
120 			}
121 			break;
122 		case 'n':
123 			num_threads = atoi(optarg);
124 			if (num_threads <= 0) {
125 				usage(argv[0]);
126 				exit(-1);
127 			}
128 			break;
129 		case 'm':
130 			method = optarg;
131 			break;
132 		case 'l':
133 			buflen = atoi(optarg) * 1024;
134 			if (buflen <= 0) {
135 				usage(argv[0]);
136 				exit(-1);
137 			}
138 			break;
139 		case 'a':
140 			prememcpy = atoi(optarg);
141 			if (prememcpy != 0 && prememcpy != 1) {
142 				usage(argv[0]);
143 				exit(-1);
144 			}
145 			break;
146 		case 'b':
147 			postmemcpy = atoi(optarg);
148 			if (postmemcpy != 0 && postmemcpy != 1) {
149 				usage(argv[0]);
150 				exit(-1);
151 			}
152 			break;
153 		case 'v':
154 			verbose = 1;
155 			break;
156 		default:
157 			usage(argv[0]);
158 			exit(0);
159 		}
160 	}
161 
162 	/* Check method str and set algorithm_func */
163 	for (i = 0; algs[i].name != NULL; i++) {
164 		if (!strcmp(method, algs[i].name)) {
165 			alg_choose = algs[i];
166 			break;
167 		}
168 	}
169 	if (algs[i].name == NULL) {
170 		usage(argv[0]);
171 		exit(-1);
172 	}
173 
174 	notice(argv[0], &alg_choose);
175 	rounds_buf = alg_choose.rounds_nbuf;
176 
177 	clients = (pthread_t *) calloc(num_threads + 1, sizeof(pthread_t));
178 	id = (int32_t *) calloc(num_threads + 1, sizeof(int32_t));
179 
180 	printf("Start %i threads, use %s function\n", num_threads, alg_choose.name);
181 
182 	for (i = 0; i < num_threads; i++) {
183 		id[i] = i;
184 
185 		ret =
186 		    pthread_create(&clients[i], NULL, alg_choose.thread_func, (void *)&id[i]);
187 
188 		if (ret != 0) {
189 			printf("Failed to create thread %i: %s", i, strerror(ret));
190 			exit(-1);
191 		}
192 		printfv("Thread %i is created\n", i);
193 	}
194 
195 	for (i = 0; i < num_threads; i++) {
196 		pthread_join(clients[i], (void *)&count);
197 		sum += count;
198 	}
199 	double loop_unit = ((double)buflen) * rounds_buf / run_secs / 1024 / 1024;
200 	printf("Sum of rounds is %ld\n"
201 	       "Average throughput(MB/s) is %.2f\n"
202 	       "Total throughput(MB/s) is %.2f\n",
203 	       sum, (double)sum / i * loop_unit, (double)sum * loop_unit);
204 
205 	exit(0);
206 }
207