parse_logs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/perl
  2. # Parse the log output files of run-experiment
  3. # Send concatenated log files to stdin, or list them on the command
  4. # line.
  5. use strict;
  6. my $mode = '';
  7. my $depth = 0;
  8. my $numops = 0;
  9. my $who = 0;
  10. my $what = '';
  11. my $setupsize = 0;
  12. my $opsize = 0;
  13. my @seconds = (0, 0);
  14. my $netsetup = '';
  15. my %floram_s_data = ();
  16. my %floram_kib_data = ();
  17. while(<>) {
  18. chomp;
  19. if (/Network setup: (.*)/) {
  20. $netsetup = "$1 ";
  21. next;
  22. }
  23. if (/===== Running floram (\S+) (\d+) (\d+)/) {
  24. $mode = $1;
  25. $depth = $2;
  26. $numops = $3;
  27. @seconds = (0,0);
  28. $what = '';
  29. $setupsize = 0;
  30. $opsize = 0;
  31. next;
  32. }
  33. if (/===== P([01]) output/) {
  34. $who = $1;
  35. next;
  36. }
  37. if (/ORAM ACCESS \(SETUP/) {
  38. $what = 'SETUP';
  39. next;
  40. }
  41. if (/ORAM ACCESS \(READ|WRITE/) {
  42. $what = 'OP';
  43. next;
  44. }
  45. if (/Total time: (\d+\.?\d*) s/) {
  46. $seconds[$who] = $1;
  47. next;
  48. }
  49. if (/^\d+,8,/) {
  50. my @F = split(/,/);
  51. my @sizes = ();
  52. my $i;
  53. for ($i=4;$i<=$#F;$i+=3) {
  54. push(@sizes, $F[$i]);
  55. }
  56. if ($what eq '') {
  57. die "Unrecognized data line\n";
  58. }
  59. if ($what eq 'SETUP') {
  60. $setupsize += $sizes[0];
  61. } else {
  62. foreach (@sizes) { $opsize += $_; }
  63. }
  64. }
  65. $what = '';
  66. if (/===== End/) {
  67. my $label = "Floram $mode $depth $netsetup$numops";
  68. my $maxsecs = $seconds[0];
  69. $maxsecs = $seconds[1] if $seconds[1] > $maxsecs;
  70. &accum_data(\%floram_s_data, $label, $maxsecs);
  71. # The setupsize and opsize are the _sum_ for the two parties, so
  72. # add them to get the total size for both parties, and divide by
  73. # 2 to get the average size for each party
  74. my $bytes = ($setupsize + $opsize) / 2;
  75. my $kib = $bytes / 1024;
  76. &accum_data(\%floram_kib_data, $label, $kib);
  77. }
  78. }
  79. # Convert the data (in the form [n, sum, sum_squares]) to statistics (in
  80. # the form [mean, variance])
  81. my %floram_s_stats = ();
  82. my %floram_kib_stats = ();
  83. &statsify(\%floram_s_stats, \%floram_s_data);
  84. &statsify(\%floram_kib_stats, \%floram_kib_data);
  85. # Output the data
  86. &output_stats(\%floram_s_stats, "s");
  87. &output_stats(\%floram_kib_stats, "KiB");
  88. # Subroutines
  89. # Pass:
  90. # - a reference to a dictionary
  91. # - the key into that dictionary
  92. # - the new data point
  93. # Data is stored in the dictionary as a triple (n, sum, sum_squares)
  94. sub accum_data {
  95. my ($dict, $key, $data) = @_;
  96. $dict->{$key} = [0, 0, 0] unless defined $dict->{$key};
  97. $dict->{$key}->[0] += 1;
  98. $dict->{$key}->[1] += $data;
  99. $dict->{$key}->[2] += ($data * $data);
  100. }
  101. # Convert data (in the form [n, sum, sum_squares]) to statistics (in
  102. # the form [mean, variance])
  103. sub statsify {
  104. my ($sdict, $ddict) = @_;
  105. my $key;
  106. foreach $key (keys %$ddict) {
  107. my $data = $ddict->{$key};
  108. my $n = $data->[0];
  109. my $sum = $data->[1];
  110. my $sumsq = $data->[2];
  111. if ($n == 0) {
  112. $sdict->{$key} = [undef, undef];
  113. } elsif ($n == 1) {
  114. $sdict->{$key} = [$sum, undef];
  115. } else {
  116. $sdict->{$key} = [$sum/$n, ($sumsq - ($sum*$sum/$n))/($n-1)];
  117. }
  118. }
  119. }
  120. # Turn a stat array [mean, variance] into a string to display
  121. sub statstr {
  122. my $data = $_[0];
  123. if (defined $data->[1]) {
  124. my $mean = $data->[0];
  125. my $stddev = $data->[1] > 0 ? sqrt($data->[1]) : 0;
  126. return "$mean ± $stddev";
  127. } elsif (defined $data->[0]) {
  128. return $data->[0];
  129. } else {
  130. return "none"
  131. }
  132. }
  133. # Output the stats in the given dictionary. Append $phase to the
  134. # protocol name, and add $units to the end.
  135. sub output_stats {
  136. my ($dict, $units) = @_;
  137. my $label;
  138. foreach $label (sort keys %$dict) {
  139. print $label, " ", &statstr($dict->{$label}), " $units\n";
  140. }
  141. }