tcrypt_speed_compare.py 5.7 KB

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