#!/usr/bin/perl # Parse the log output files of run-experiment # Send concatenated log files to stdin, or list them on the command # line. use strict; my $mode = ''; my $depth = 0; my $numops = 0; my $who = 0; my $what = ''; my $setupsize = 0; my $opsize = 0; my @seconds = (0, 0); my $netsetup = ''; my %floram_s_data = (); my %floram_kib_data = (); while(<>) { chomp; if (/Network setup: (.*)/) { $netsetup = "$1 "; next; } if (/===== Running floram (\S+) (\d+) (\d+)/) { $mode = $1; $depth = $2; $numops = $3; @seconds = (0,0); $what = ''; $setupsize = 0; $opsize = 0; next; } if (/===== P([01]) output/) { $who = $1; next; } if (/ORAM ACCESS \(SETUP/) { $what = 'SETUP'; next; } if (/ORAM ACCESS \(READ|WRITE/) { $what = 'OP'; next; } if (/Total time: (\d+\.?\d*) s/) { $seconds[$who] = $1; next; } if (/^\d+,8,/) { my @F = split(/,/); my @sizes = (); my $i; for ($i=4;$i<=$#F;$i+=3) { push(@sizes, $F[$i]); } if ($what eq '') { die "Unrecognized data line\n"; } if ($what eq 'SETUP') { $setupsize += $sizes[0]; } else { foreach (@sizes) { $opsize += $_; } } } $what = ''; if (/===== End/) { my $label = "Floram $mode $depth $netsetup$numops"; my $maxsecs = $seconds[0]; $maxsecs = $seconds[1] if $seconds[1] > $maxsecs; &accum_data(\%floram_s_data, $label, $maxsecs); # The setupsize and opsize are the _sum_ for the two parties, so # add them to get the total size for both parties, and divide by # 2 to get the average size for each party my $bytes = ($setupsize + $opsize) / 2; my $kib = $bytes / 1024; &accum_data(\%floram_kib_data, $label, $kib); } } # Convert the data (in the form [n, sum, sum_squares]) to statistics (in # the form [mean, variance]) my %floram_s_stats = (); my %floram_kib_stats = (); &statsify(\%floram_s_stats, \%floram_s_data); &statsify(\%floram_kib_stats, \%floram_kib_data); # Output the data &output_stats(\%floram_s_stats, "s"); &output_stats(\%floram_kib_stats, "KiB"); # Subroutines # Pass: # - a reference to a dictionary # - the key into that dictionary # - the new data point # Data is stored in the dictionary as a triple (n, sum, sum_squares) sub accum_data { my ($dict, $key, $data) = @_; $dict->{$key} = [0, 0, 0] unless defined $dict->{$key}; $dict->{$key}->[0] += 1; $dict->{$key}->[1] += $data; $dict->{$key}->[2] += ($data * $data); } # Convert data (in the form [n, sum, sum_squares]) to statistics (in # the form [mean, variance]) sub statsify { my ($sdict, $ddict) = @_; my $key; foreach $key (keys %$ddict) { my $data = $ddict->{$key}; my $n = $data->[0]; my $sum = $data->[1]; my $sumsq = $data->[2]; if ($n == 0) { $sdict->{$key} = [undef, undef]; } elsif ($n == 1) { $sdict->{$key} = [$sum, undef]; } else { $sdict->{$key} = [$sum/$n, ($sumsq - ($sum*$sum/$n))/($n-1)]; } } } # Turn a stat array [mean, variance] into a string to display sub statstr { my $data = $_[0]; if (defined $data->[1]) { my $mean = $data->[0]; my $stddev = $data->[1] > 0 ? sqrt($data->[1]) : 0; return "$mean ± $stddev"; } elsif (defined $data->[0]) { return $data->[0]; } else { return "none" } } # Output the stats in the given dictionary. Append $phase to the # protocol name, and add $units to the end. sub output_stats { my ($dict, $units) = @_; my $label; foreach $label (sort keys %$dict) { print $label, " ", &statstr($dict->{$label}), " $units\n"; } }