1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3# 4# Copyright (C) xFusion Digital Technologies Co., Ltd., 2023 5# 6# Author: Wang Jinchao <wangjinchao@xfusion.com> 7# 8""" 9A tool for comparing tcrypt speed test logs. 10 11Please note that for such a comparison, stability depends 12on whether we allow frequency to float or pin the frequency. 13 14Both support tests for operations within one second and 15cycles of operation. 16For example, use it in the bash script below. 17 18```bash 19#!/bin/bash 20 21# log file prefix 22seq_num=0 23 24# When sec=0, it will perform cycle tests; 25# otherwise, it indicates the duration of a single test 26sec=0 27num_mb=8 28mode=211 29 30# base speed test 31lsmod | grep pcrypt && modprobe -r pcrypt 32dmesg -C 33modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3 34modprobe tcrypt mode=${mode} sec=${sec} num_mb=${num_mb} 35dmesg > ${seq_num}_base_dmesg.log 36 37# new speed test 38lsmod | grep pcrypt && modprobe -r pcrypt 39dmesg -C 40modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3 41modprobe tcrypt mode=${mode} sec=${sec} num_mb=${num_mb} 42dmesg > ${seq_num}_new_dmesg.log 43lsmod | grep pcrypt && modprobe -r pcrypt 44 45tools/crypto/tcrypt/tcrypt_speed_compare.py \ 46 ${seq_num}_base_dmesg.log \ 47 ${seq_num}_new_dmesg.log \ 48 >${seq_num}_compare.log 49grep 'average' -A2 -B0 --group-separator="" ${seq_num}_compare.log 50``` 51""" 52 53import sys 54import re 55 56 57def parse_title(line): 58 pattern = r'tcrypt: testing speed of (.*?) (encryption|decryption)' 59 match = re.search(pattern, line) 60 if match: 61 alg = match.group(1) 62 op = match.group(2) 63 return alg, op 64 else: 65 return "", "" 66 67 68def parse_item(line): 69 pattern_operations = r'\((\d+) bit key, (\d+) byte blocks\): (\d+) operations' 70 pattern_cycles = r'\((\d+) bit key, (\d+) byte blocks\): 1 operation in (\d+) cycles' 71 match = re.search(pattern_operations, line) 72 if match: 73 res = { 74 "bit_key": int(match.group(1)), 75 "byte_blocks": int(match.group(2)), 76 "operations": int(match.group(3)), 77 } 78 return res 79 80 match = re.search(pattern_cycles, line) 81 if match: 82 res = { 83 "bit_key": int(match.group(1)), 84 "byte_blocks": int(match.group(2)), 85 "cycles": int(match.group(3)), 86 } 87 return res 88 89 return None 90 91 92def parse(filepath): 93 result = {} 94 alg, op = "", "" 95 with open(filepath, 'r') as file: 96 for line in file: 97 if not line: 98 continue 99 _alg, _op = parse_title(line) 100 if _alg: 101 alg, op = _alg, _op 102 if alg not in result: 103 result[alg] = {} 104 if op not in result[alg]: 105 result[alg][op] = [] 106 continue 107 parsed_result = parse_item(line) 108 if parsed_result: 109 result[alg][op].append(parsed_result) 110 return result 111 112 113def merge(base, new): 114 merged = {} 115 for alg in base.keys(): 116 merged[alg] = {} 117 for op in base[alg].keys(): 118 if op not in merged[alg]: 119 merged[alg][op] = [] 120 for index in range(len(base[alg][op])): 121 merged_item = { 122 "bit_key": base[alg][op][index]["bit_key"], 123 "byte_blocks": base[alg][op][index]["byte_blocks"], 124 } 125 if "operations" in base[alg][op][index].keys(): 126 merged_item["base_ops"] = base[alg][op][index]["operations"] 127 merged_item["new_ops"] = new[alg][op][index]["operations"] 128 else: 129 merged_item["base_cycles"] = base[alg][op][index]["cycles"] 130 merged_item["new_cycles"] = new[alg][op][index]["cycles"] 131 132 merged[alg][op].append(merged_item) 133 return merged 134 135 136def format(merged): 137 for alg in merged.keys(): 138 for op in merged[alg].keys(): 139 base_sum = 0 140 new_sum = 0 141 differ_sum = 0 142 differ_cnt = 0 143 print() 144 hlen = 80 145 print("="*hlen) 146 print(f"{alg}") 147 print(f"{' '*(len(alg)//3) + op}") 148 print("-"*hlen) 149 key = "" 150 if "base_ops" in merged[alg][op][0]: 151 key = "ops" 152 print(f"bit key | byte blocks | base ops | new ops | differ(%)") 153 else: 154 key = "cycles" 155 print(f"bit key | byte blocks | base cycles | new cycles | differ(%)") 156 for index in range(len(merged[alg][op])): 157 item = merged[alg][op][index] 158 base_cnt = item[f"base_{key}"] 159 new_cnt = item[f"new_{key}"] 160 base_sum += base_cnt 161 new_sum += new_cnt 162 differ = round((new_cnt - base_cnt)*100/base_cnt, 2) 163 differ_sum += differ 164 differ_cnt += 1 165 bit_key = item["bit_key"] 166 byte_blocks = item["byte_blocks"] 167 print( 168 f"{bit_key:<7} | {byte_blocks:<11} | {base_cnt:<11} | {new_cnt:<11} | {differ:<8}") 169 average_speed_up = "{:.2f}".format(differ_sum/differ_cnt) 170 ops_total_speed_up = "{:.2f}".format( 171 (base_sum - new_sum) * 100 / base_sum) 172 print('-'*hlen) 173 print(f"average differ(%s) | total_differ(%)") 174 print('-'*hlen) 175 print(f"{average_speed_up:<21} | {ops_total_speed_up:<10}") 176 print('='*hlen) 177 178 179def main(base_log, new_log): 180 base = parse(base_log) 181 new = parse(new_log) 182 merged = merge(base, new) 183 format(merged) 184 185 186if __name__ == "__main__": 187 if len(sys.argv) != 3: 188 print(f"usage: {sys.argv[0]} base_log new_log") 189 exit(-1) 190 main(sys.argv[1], sys.argv[2]) 191