aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/crypto/tcrypt/tcrypt_speed_compare.py
blob: f3f5783cdc066bf00d7578ad2a444211945bcfe7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) xFusion Digital Technologies Co., Ltd., 2023
#
# Author: Wang Jinchao <wangjinchao@xfusion.com>
#
"""
A tool for comparing tcrypt speed test logs.

Please note that for such a comparison, stability depends
on whether we allow frequency to float or pin the frequency.

Both support tests for operations within one second and
cycles of operation.
For example, use it in the bash script below.

```bash
#!/bin/bash

# log file prefix
seq_num=0

# When sec=0, it will perform cycle tests;
# otherwise, it indicates the duration of a single test
sec=0
num_mb=8
mode=211

# base speed test
lsmod | grep pcrypt && modprobe -r pcrypt
dmesg -C
modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3
modprobe tcrypt mode=${mode} sec=${sec} num_mb=${num_mb}
dmesg > ${seq_num}_base_dmesg.log

# new speed test
lsmod | grep pcrypt && modprobe -r pcrypt
dmesg -C
modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3
modprobe tcrypt mode=${mode} sec=${sec} num_mb=${num_mb}
dmesg > ${seq_num}_new_dmesg.log
lsmod | grep pcrypt && modprobe -r pcrypt

tools/crypto/tcrypt/tcrypt_speed_compare.py \
    ${seq_num}_base_dmesg.log \
    ${seq_num}_new_dmesg.log  \
        >${seq_num}_compare.log
grep 'average' -A2 -B0 --group-separator="" ${seq_num}_compare.log
```
"""

import sys
import re


def parse_title(line):
    pattern = r'tcrypt: testing speed of (.*?) (encryption|decryption)'
    match = re.search(pattern, line)
    if match:
        alg = match.group(1)
        op = match.group(2)
        return alg, op
    else:
        return "", ""


def parse_item(line):
    pattern_operations = r'\((\d+) bit key, (\d+) byte blocks\): (\d+) operations'
    pattern_cycles = r'\((\d+) bit key, (\d+) byte blocks\): 1 operation in (\d+) cycles'
    match = re.search(pattern_operations, line)
    if match:
        res = {
            "bit_key": int(match.group(1)),
            "byte_blocks": int(match.group(2)),
            "operations": int(match.group(3)),
        }
        return res

    match = re.search(pattern_cycles, line)
    if match:
        res = {
            "bit_key": int(match.group(1)),
            "byte_blocks": int(match.group(2)),
            "cycles": int(match.group(3)),
        }
        return res

    return None


def parse(filepath):
    result = {}
    alg, op = "", ""
    with open(filepath, 'r') as file:
        for line in file:
            if not line:
                continue
            _alg, _op = parse_title(line)
            if _alg:
                alg, op = _alg, _op
                if alg not in result:
                    result[alg] = {}
                if op not in result[alg]:
                    result[alg][op] = []
                continue
            parsed_result = parse_item(line)
            if parsed_result:
                result[alg][op].append(parsed_result)
    return result


def merge(base, new):
    merged = {}
    for alg in base.keys():
        merged[alg] = {}
        for op in base[alg].keys():
            if op not in merged[alg]:
                merged[alg][op] = []
            for index in range(len(base[alg][op])):
                merged_item = {
                    "bit_key": base[alg][op][index]["bit_key"],
                    "byte_blocks": base[alg][op][index]["byte_blocks"],
                }
                if "operations" in base[alg][op][index].keys():
                    merged_item["base_ops"] = base[alg][op][index]["operations"]
                    merged_item["new_ops"] = new[alg][op][index]["operations"]
                else:
                    merged_item["base_cycles"] = base[alg][op][index]["cycles"]
                    merged_item["new_cycles"] = new[alg][op][index]["cycles"]

                merged[alg][op].append(merged_item)
    return merged


def format(merged):
    for alg in merged.keys():
        for op in merged[alg].keys():
            base_sum = 0
            new_sum = 0
            differ_sum = 0
            differ_cnt = 0
            print()
            hlen = 80
            print("="*hlen)
            print(f"{alg}")
            print(f"{' '*(len(alg)//3) + op}")
            print("-"*hlen)
            key = ""
            if "base_ops" in merged[alg][op][0]:
                key = "ops"
                print(f"bit key | byte blocks | base ops    | new ops     | differ(%)")
            else:
                key = "cycles"
                print(f"bit key | byte blocks | base cycles | new cycles  | differ(%)")
            for index in range(len(merged[alg][op])):
                item = merged[alg][op][index]
                base_cnt = item[f"base_{key}"]
                new_cnt = item[f"new_{key}"]
                base_sum += base_cnt
                new_sum += new_cnt
                differ = round((new_cnt - base_cnt)*100/base_cnt, 2)
                differ_sum += differ
                differ_cnt += 1
                bit_key = item["bit_key"]
                byte_blocks = item["byte_blocks"]
                print(
                    f"{bit_key:<7} | {byte_blocks:<11} | {base_cnt:<11} | {new_cnt:<11} | {differ:<8}")
            average_speed_up = "{:.2f}".format(differ_sum/differ_cnt)
            ops_total_speed_up = "{:.2f}".format(
                (base_sum - new_sum) * 100 / base_sum)
            print('-'*hlen)
            print(f"average differ(%s)    | total_differ(%)")
            print('-'*hlen)
            print(f"{average_speed_up:<21} | {ops_total_speed_up:<10}")
            print('='*hlen)


def main(base_log, new_log):
    base = parse(base_log)
    new = parse(new_log)
    merged = merge(base, new)
    format(merged)


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(f"usage: {sys.argv[0]} base_log new_log")
        exit(-1)
    main(sys.argv[1], sys.argv[2])