blob: a7228324c163aed2ecfb70ca63856fc4d6e0ae94 [file] [log] [blame]
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +01001#include <ctype.h>
2#include <sched.h>
Srinath Sridharan96276382016-03-10 10:22:30 -08003#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
Srinath Sridharan96276382016-03-10 10:22:30 -08006#include <sys/resource.h>
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +01007#include <sys/time.h>
8#include <unistd.h>
Srinath Sridharan96276382016-03-10 10:22:30 -08009#define USEC_PER_SEC 1000000ULL
10#define MAX_COUNT 1000000000ULL
11#define NUM_INSTS_GARBAGE 18
12
13// Contains information about benchmark options.
14typedef struct {
15 int cpu_to_lock;
16 int locked_freq;
17} command_data_t;
18
19void usage() {
20 printf("--------------------------------------------------------------------------------\n");
21 printf("Usage:");
22 printf(" crypto [--cpu_to_lock CPU] [--locked_freq FREQ_IN_KHZ]\n\n");
23 printf("!!!!!!Lock the desired core to a desired frequency before invoking this benchmark.\n");
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010024 printf("Hint: Set scaling_max_freq=scaling_min_freq=FREQ_IN_KHZ. FREQ_IN_KHZ "
25 "can be obtained from scaling_available_freq\n");
Srinath Sridharan96276382016-03-10 10:22:30 -080026 printf("--------------------------------------------------------------------------------\n");
27}
28
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010029int processOptions(int argc, char** argv, command_data_t* cmd_data) {
Srinath Sridharan96276382016-03-10 10:22:30 -080030 // Initialize the command_flags.
31 cmd_data->cpu_to_lock = 0;
32 cmd_data->locked_freq = 1;
33 for (int i = 1; i < argc; i++) {
34 if (argv[i][0] == '-') {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010035 int* save_value = NULL;
Srinath Sridharan96276382016-03-10 10:22:30 -080036 if (strcmp(argv[i], "--cpu_to_lock") == 0) {
37 save_value = &cmd_data->cpu_to_lock;
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010038 } else if (strcmp(argv[i], "--locked_freq") == 0) {
Srinath Sridharan96276382016-03-10 10:22:30 -080039 save_value = &cmd_data->locked_freq;
40 } else {
41 printf("Unknown option %s\n", argv[i]);
42 return -1;
43 }
44 if (save_value) {
45 // Checking both characters without a strlen() call should be
46 // safe since as long as the argument exists, one character will
47 // be present (\0). And if the first character is '-', then
48 // there will always be a second character (\0 again).
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010049 if (i == argc - 1 || (argv[i + 1][0] == '-' && !isdigit(argv[i + 1][1]))) {
Srinath Sridharan96276382016-03-10 10:22:30 -080050 printf("The option %s requires one argument.\n", argv[i]);
51 return -1;
52 }
53 *save_value = (int)strtol(argv[++i], NULL, 0);
54 }
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010055 }
Srinath Sridharan96276382016-03-10 10:22:30 -080056 }
57 return 0;
58}
59/* Performs encryption on garbage values. In Cortex-A57 r0p1 and later
60 * revisions, pairs of dependent AESE/AESMC and AESD/AESIMC instructions are
61 * higher performance when adjacent, and in the described order below. */
62void garbage_encrypt() {
63 __asm__ __volatile__(
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010064 "aese v0.16b, v4.16b ;"
65 "aesmc v0.16b, v0.16b ;"
66 "aese v1.16b, v4.16b ;"
67 "aesmc v1.16b, v1.16b ;"
68 "aese v2.16b, v4.16b ;"
69 "aesmc v2.16b, v2.16b ;"
70 "aese v0.16b, v5.16b ;"
71 "aesmc v0.16b, v0.16b ;"
72 "aese v1.16b, v5.16b ;"
73 "aesmc v1.16b, v1.16b ;"
74 "aese v2.16b, v5.16b ;"
75 "aesmc v2.16b, v2.16b ;"
76 "aese v0.16b, v6.16b ;"
77 "aesmc v0.16b, v0.16b ;"
78 "aese v1.16b, v6.16b ;"
79 "aesmc v1.16b, v1.16b ;"
80 "aese v2.16b, v6.16b ;"
81 "aesmc v2.16b, v2.16b ;");
Srinath Sridharan96276382016-03-10 10:22:30 -080082}
83
84void garbage_decrypt() {
85 __asm__ __volatile__(
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +010086 "aesd v0.16b, v4.16b ;"
87 "aesimc v0.16b, v0.16b ;"
88 "aesd v1.16b, v4.16b ;"
89 "aesimc v1.16b, v1.16b ;"
90 "aesd v2.16b, v4.16b ;"
91 "aesimc v2.16b, v2.16b ;"
92 "aesd v0.16b, v5.16b ;"
93 "aesimc v0.16b, v0.16b ;"
94 "aesd v1.16b, v5.16b ;"
95 "aesimc v1.16b, v1.16b ;"
96 "aesd v2.16b, v5.16b ;"
97 "aesimc v2.16b, v2.16b ;"
98 "aesd v0.16b, v6.16b ;"
99 "aesimc v0.16b, v0.16b ;"
100 "aesd v1.16b, v6.16b ;"
101 "aesimc v1.16b, v1.16b ;"
102 "aesd v2.16b, v6.16b ;"
103 "aesimc v2.16b, v2.16b ;");
Srinath Sridharan96276382016-03-10 10:22:30 -0800104}
105
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100106int main(int argc, char** argv) {
Srinath Sridharan96276382016-03-10 10:22:30 -0800107 usage();
108 command_data_t cmd_data;
109
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100110 if (processOptions(argc, argv, &cmd_data) == -1) {
Srinath Sridharan96276382016-03-10 10:22:30 -0800111 usage();
112 return -1;
113 }
114 unsigned long long count = 0;
115 struct timeval begin_time, end_time, elapsed_time;
116 cpu_set_t cpuset;
117 CPU_ZERO(&cpuset);
118 CPU_SET(cmd_data.cpu_to_lock, &cpuset);
119 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100120 perror("sched_setaffinity failed");
121 return 1;
Srinath Sridharan96276382016-03-10 10:22:30 -0800122 }
123 gettimeofday(&begin_time, NULL);
124 while (count < MAX_COUNT) {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100125 garbage_encrypt();
126 count++;
Srinath Sridharan96276382016-03-10 10:22:30 -0800127 }
128 gettimeofday(&end_time, NULL);
129 timersub(&end_time, &begin_time, &elapsed_time);
130 fprintf(stderr, "encrypt: %llu us\n",
131 elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec);
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100132 fprintf(stderr, "encrypt instructions: %llu\n", MAX_COUNT * NUM_INSTS_GARBAGE);
Srinath Sridharan96276382016-03-10 10:22:30 -0800133 fprintf(stderr, "encrypt instructions per second: %f\n",
134 (float)(MAX_COUNT * NUM_INSTS_GARBAGE * USEC_PER_SEC) /
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100135 (elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec));
Srinath Sridharan96276382016-03-10 10:22:30 -0800136 if (cmd_data.locked_freq != 0) {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100137 fprintf(stderr, "encrypt instructions per cycle: %f\n",
138 (float)(MAX_COUNT * NUM_INSTS_GARBAGE * USEC_PER_SEC) /
139 ((elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec) * 1000 *
140 cmd_data.locked_freq));
Srinath Sridharan96276382016-03-10 10:22:30 -0800141 }
142 printf("--------------------------------------------------------------------------------\n");
143
144 count = 0;
145 gettimeofday(&begin_time, NULL);
146 while (count < MAX_COUNT) {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100147 garbage_decrypt();
148 count++;
Srinath Sridharan96276382016-03-10 10:22:30 -0800149 }
150 gettimeofday(&end_time, NULL);
151 timersub(&end_time, &begin_time, &elapsed_time);
152 fprintf(stderr, "decrypt: %llu us\n",
153 elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec);
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100154 fprintf(stderr, "decrypt instructions: %llu\n", MAX_COUNT * NUM_INSTS_GARBAGE);
Srinath Sridharan96276382016-03-10 10:22:30 -0800155 fprintf(stderr, "decrypt instructions per second: %f\n",
156 (float)(MAX_COUNT * NUM_INSTS_GARBAGE * USEC_PER_SEC) /
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100157 (elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec));
Srinath Sridharan96276382016-03-10 10:22:30 -0800158 if (cmd_data.locked_freq != 0) {
Thiébaud Weksteen135c65d2020-10-26 13:33:47 +0100159 fprintf(stderr, "decrypt instructions per cycle: %f\n",
160 (float)(MAX_COUNT * NUM_INSTS_GARBAGE * USEC_PER_SEC) /
161 ((elapsed_time.tv_sec * USEC_PER_SEC + elapsed_time.tv_usec) * 1000 *
162 cmd_data.locked_freq));
Srinath Sridharan96276382016-03-10 10:22:30 -0800163 }
164 return 0;
165}