getpercent 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. # Generate an ascii percentage summary from lmbench result files.
  2. # Usage: getpercent file file file...
  3. #
  4. # Hacked into existence by Larry McVoy (lm@sun.com now lm@sgi.com).
  5. # Copyright (c) 1994 Larry McVoy. GPLed software.
  6. # $Id$
  7. eval 'exec perl -Ssw $0 "$@"'
  8. if 0;
  9. $n = 0; # apparently, hpux doesn't init to 0????
  10. foreach $file (@ARGV) {
  11. push(@files, $file);
  12. open(FD, $file) || die "$0: can't open $file";
  13. $file =~ s|/|-|;
  14. $file =~ s/\.\d+//;
  15. push(@file, $file);
  16. while (<FD>) {
  17. chop;
  18. next if m|scripts/lmbench: /dev/tty|;
  19. if (/^\[lmbench/) {
  20. split;
  21. push(@uname, "@_");
  22. }
  23. if (/Mhz/) {
  24. split;
  25. push(@misc_mhz, $_[0]);
  26. }
  27. if (/^Null syscall:/) {
  28. split;
  29. push(@lat_nullsys, $_[2]);
  30. }
  31. if (/^Pipe latency:/) {
  32. split;
  33. push(@lat_pipe, $_[2]);
  34. }
  35. if (/UDP latency using localhost:/) {
  36. split;
  37. push(@lat_udp_local, $_[4]);
  38. }
  39. if (/TCP latency using localhost/) {
  40. split;
  41. push(@lat_tcp_local, $_[4]);
  42. }
  43. if (/RPC.udp latency using localhost/) {
  44. split;
  45. push(@lat_rpc_udp_local, $_[4]);
  46. }
  47. if (/RPC.tcp latency using localhost/) {
  48. split;
  49. push(@lat_rpc_tcp_local, $_[4]);
  50. }
  51. if (/^Process fork.exit/) {
  52. split;
  53. push(@lat_nullproc, $_[2]);
  54. }
  55. if (/^Process fork.execve:/) {
  56. split;
  57. push(@lat_simpleproc, $_[2]);
  58. }
  59. if (/^Process fork..bin.sh/) {
  60. split;
  61. push(@lat_shproc, $_[3]);
  62. }
  63. if (/size=0 ovr=/) {
  64. while (<FD>) {
  65. next unless /^2/;
  66. split;
  67. push(@lat_ctx, $_[1]);
  68. last;
  69. }
  70. while (<FD>) {
  71. next unless /^8/;
  72. split;
  73. push(@lat_ctx8, $_[1]);
  74. last;
  75. }
  76. }
  77. if (/^Pipe bandwidth/) {
  78. split;
  79. push(@bw_pipe, $_[2]);
  80. }
  81. if (/^Socket bandwidth using localhost/) {
  82. split;
  83. push(@bw_tcp_local, $_[4]);
  84. }
  85. if (/^File .* write bandwidth/) {
  86. split;
  87. $bw = sprintf("%.2f", $_[4] / 1024.);
  88. push(@bw_file, $bw);
  89. }
  90. if (/^"mappings/) {
  91. $value = &getbiggest("memory mapping timing");
  92. push(@lat_mappings, $value);
  93. }
  94. if (/^"read bandwidth/) {
  95. $value = &getbiggest("reread timing");
  96. push(@bw_reread, $value);
  97. }
  98. if (/^"Mmap read bandwidth/) {
  99. $value = &getbiggest("mmap reread timing");
  100. push(@bw_mmap, $value);
  101. }
  102. if (/^"libc bcopy unaligned/) {
  103. $value = &getbiggest("libc bcopy timing");
  104. push(@bw_bcopy_libc, $value);
  105. }
  106. if (/^"unrolled bcopy unaligned/) {
  107. $value = &getbiggest("unrolled bcopy timing");
  108. push(@bw_bcopy_unrolled, $value);
  109. }
  110. if (/^Memory read/) {
  111. $value = &getbiggest("memory read & sum timing");
  112. push(@bw_mem_rdsum, $value);
  113. }
  114. if (/^Memory write/) {
  115. $value = &getbiggest("memory write timing");
  116. push(@bw_mem_wr, $value);
  117. }
  118. if (/^"stride=128/) {
  119. $save = -1;
  120. while (<FD>) {
  121. if (/^0.00098\s/) {
  122. split;
  123. push(@lat_l1, $_[1]);
  124. } elsif (/^0.12500\s/) {
  125. split;
  126. push(@lat_l2, $_[1]);
  127. } elsif (/^[45678].00000\s/) {
  128. split;
  129. $size = $_[0];
  130. $save = $_[1];
  131. last if /^8.00000\s/;
  132. } elsif (/^\s*$/) {
  133. last;
  134. }
  135. }
  136. if (!/^8/) {
  137. warn "$file: No 8MB memory latency, using $size\n";
  138. }
  139. push(@lat_mem, $save);
  140. }
  141. if (/^"stride=8192/) { # XXX assumes <= 8K pagesize
  142. $tbl = -1;
  143. while (<FD>) {
  144. if (/^[45678].00000\s/) {
  145. split;
  146. $tlb = $_[1];
  147. $size = $_[0];
  148. last if /^8.00000\s/;
  149. }
  150. }
  151. if (!/^8/) {
  152. warn "$file: No 8MB tlb latency, using $size\n";
  153. }
  154. push(@lat_tlb, $tlb);
  155. }
  156. }
  157. foreach $array (
  158. 'misc_mhz', 'lat_nullsys', 'lat_pipe', 'lat_udp_local',
  159. 'lat_tcp_local', 'lat_rpc_udp_local',
  160. 'lat_rpc_tcp_local', 'lat_nullproc', 'lat_simpleproc',
  161. 'lat_ctx', 'lat_ctx8', 'bw_pipe', 'bw_tcp_local',
  162. 'bw_file', 'lat_mappings', 'bw_reread', 'bw_mmap',
  163. 'bw_bcopy_libc', 'bw_bcopy_unrolled', 'bw_mem_rdsum',
  164. 'bw_mem_wr', 'lat_l1', 'lat_l2', 'lat_mem', 'lat_tlb',
  165. ) {
  166. eval "if (\$#$array != $n) {
  167. warn \"No data for $array in $file\n\";
  168. push(\@$array, -1);
  169. }";
  170. }
  171. $n++;
  172. }
  173. exit 0;
  174. # Input looks like
  175. # "benchmark name
  176. # size value
  177. # ....
  178. # <blank line>
  179. #
  180. # Return the biggest vvalue before the blank line.
  181. sub getbiggest
  182. {
  183. local($msg) = @_;
  184. undef $save;
  185. $value = 0;
  186. while (<FD>) {
  187. last if /^\s*$/;
  188. $save = $_ if /^\d\./;
  189. }
  190. if (defined $save) {
  191. $_ = $save;
  192. @d = split;
  193. $value = $d[1];
  194. if (int($d[0]) < 8) {
  195. warn "$file: using $d[0] size for $msg\n";
  196. }
  197. } else {
  198. warn "$file: no data for $msg\n";
  199. }
  200. $value;
  201. }
  202. print<<EOF;
  203. L M B E N C H 1 . 0 S U M M A R Y
  204. ------------------------------------
  205. Comparison to best of the breed
  206. -------------------------------
  207. (Best numbers are starred, i.e., *123)
  208. Processor, Processes - factor slower than the best
  209. --------------------------------------------------
  210. Host OS Mhz Null Null Simple /bin/sh Mmap 2-proc 8-proc
  211. Syscall Process Process Process lat ctxsw ctxsw
  212. --------- ------------- ---- ------- ------- ------- ------- ---- ------ ------
  213. EOF
  214. for ($i = 0; $i <= $#uname; $i++) {
  215. printf "%-9.9s %13.13s ", $file[$i], &getos($uname[$i]);
  216. printf "%4.0f %7s %7s %7s %7s %4s %6s %6s\n",
  217. $misc_mhz[$i],
  218. &smaller(@lat_nullsys, $i, 0),
  219. &smaller(@lat_nullproc, $i, 1024),
  220. &smaller(@lat_simpleproc, $i, 1024),
  221. &smaller(@lat_shproc, $i, 1024),
  222. &smaller(@lat_mappings, $i, 0),
  223. &smaller(@lat_ctx, $i, 0),
  224. &smaller(@lat_ctx8, $i, 0);
  225. }
  226. print<<EOF;
  227. *Local* Communication latencies - factor slower than the best
  228. -------------------------------------------------------------
  229. Host OS Pipe UDP RPC/ TCP RPC/
  230. UDP TCP
  231. --------- ------------- ------- ------- ------- ------- -------
  232. EOF
  233. for ($i = 0; $i <= $#uname; $i++) {
  234. printf "%-9.9s %13.13s ", $file[$i], &getos($uname[$i]);
  235. printf "%7s %7s %7s %7s %7s\n",
  236. &smaller(@lat_pipe, $i, 0),
  237. &smaller(@lat_udp_local, $i, 0),
  238. &smaller(@lat_rpc_udp_local, $i, 0),
  239. &smaller(@lat_tcp_local, $i, 0),
  240. &smaller(@lat_rpc_tcp_local, $i, 0);
  241. }
  242. print<<EOF;
  243. *Local* Communication bandwidths - percentage of the best
  244. ---------------------------------------------------------
  245. Host OS Pipe TCP File Mmap Bcopy Bcopy Mem Mem
  246. reread reread (libc) (hand) read write
  247. --------- ------------- ---- ---- ------ ------ ------ ------ ---- -----
  248. EOF
  249. for ($i = 0; $i <= $#uname; $i++) {
  250. printf "%-9.9s %13.13s ", $file[$i], &getos($uname[$i]);
  251. printf "%4s %4s %6s %6s %6s %6s %4s %5s\n",
  252. &bigger(@bw_pipe, $i),
  253. &bigger(@bw_tcp_local, $i),
  254. &bigger(@bw_reread, $i),
  255. &bigger(@bw_mmap, $i),
  256. &bigger(@bw_bcopy_libc, $i),
  257. &bigger(@bw_bcopy_unrolled, $i),
  258. &bigger(@bw_mem_rdsum, $i),
  259. &bigger(@bw_mem_wr, $i);
  260. }
  261. print<<EOF;
  262. Memory latencies in nanoseconds - factor slower than the best
  263. (WARNING - may not be correct, check graphs)
  264. -------------------------------------------------------------
  265. Host OS Mhz L1 \$ L2 \$ Main mem Guesses
  266. --------- ------------- --- ---- ---- -------- -------
  267. EOF
  268. for ($i = 0; $i <= $#uname; $i++) {
  269. printf "%-9.9s %13.13s %3d",
  270. $file[$i], &getos($uname[$i]), $misc_mhz[$i];
  271. if ($lat_l1[$i] < 0) {
  272. printf "%6s %6s %11s %s",
  273. "-", "-", "-",
  274. "Bad mhz?";
  275. } else {
  276. $msg = &check_caches;
  277. if ($msg =~ /L1/) {
  278. $lat_l1[$i] = -1;
  279. } elsif ($msg =~ /L2/) {
  280. $lat_l2[$i] = -1;
  281. }
  282. printf "%6s %6s %11s",
  283. &smaller(@lat_l1, $i, 0),
  284. &smaller(@lat_l2, $i, 0),
  285. &smaller(@lat_mem, $i, 0);
  286. if ($msg =~ /L/) {
  287. print "$msg";
  288. }
  289. }
  290. print "\n";
  291. }
  292. exit 0;
  293. # Return factor of the smallest number.
  294. sub smaller
  295. {
  296. local(@values) = @_;
  297. local($which, $min, $i, $units);
  298. $units = pop(@values);
  299. $which = pop(@values);
  300. $min = 0x7fffffff;
  301. foreach $i (@values) {
  302. next if $i == -1 || $i == 0;
  303. $min = $i if ($min > $i);
  304. }
  305. if ($values[$which] == $min) {
  306. #"***";
  307. if ($units == 1024) {
  308. sprintf("*%.1fK", $values[$which]/1024.);
  309. } else {
  310. sprintf("*%d", $values[$which]);
  311. }
  312. } elsif ($values[$which] == -1) {
  313. "???";
  314. } elsif ($values[$which] == 0) {
  315. "???";
  316. } elsif ($values[$which] / $min < 10.0) {
  317. sprintf("%.1f", $values[$which] / $min);
  318. } else {
  319. sprintf("%.0f", $values[$which] / $min);
  320. }
  321. }
  322. # Return closeness to the largest number as a percentage.
  323. # Exact match is 100%, smaller numbers are like 15%.
  324. sub bigger
  325. {
  326. local(@values) = @_;
  327. local($which, $max, $i);
  328. $which = pop(@values);
  329. $max = 0;
  330. foreach $i (@values) {
  331. $max = $i if ($max < $i);
  332. }
  333. if ($values[$which] == $max) {
  334. sprintf("*%d", $values[$which]);
  335. } else {
  336. sprintf("%d%%", $values[$which] / $max * 100);
  337. }
  338. }
  339. # Try and create sensible names from uname -a output
  340. sub getos
  341. {
  342. local(@info);
  343. @info = split(/\s+/, $_[0]);
  344. "$info[3] $info[5]";
  345. }
  346. # Return true if the values differe by less than 10%
  347. sub same
  348. {
  349. local($a, $b) = @_;
  350. if ($a > $b) {
  351. $percent = (($a - $b) / $a) * 100;
  352. } else {
  353. $percent = (($b - $a) / $b) * 100;
  354. }
  355. return ($percent <= 20);
  356. }
  357. sub check_caches
  358. {
  359. if (!&same($lat_l1[$i], $lat_l2[$i]) &&
  360. &same($lat_l2[$i], $lat_mem[$i])) {
  361. " No L2 cache?";
  362. } elsif (&same($lat_l1[$i], $lat_l2[$i])) {
  363. " No L1 cache?";
  364. }
  365. }