Browse code

implove poolsize.pl

aCaB authored on 2009/09/30 07:55:26
Showing 1 changed files
... ...
@@ -3,28 +3,41 @@
3 3
 use strict;
4 4
 use warnings;
5 5
 
6
-# usage poolsize.pl < mpool_spamfile
6
+use constant PERM => 0;
7
+use constant TEMP => 1;
8
+use constant MAXA => 2;
9
+use constant REAS => 3;
10
+
11
+use constant TAKE => PERM;
12
+
13
+# usage poolsize.pl < mpool_allocfile
7 14
 
8 15
 my $sizeof_void_ptr;
9 16
 my $overhead = 0;
10 17
 
11 18
 my %ptrs;
12 19
 my %sizes;
20
+my %maxes;
13 21
 
14 22
 my $maxsz = 0;
15 23
 
24
+print STDERR "Parsing allocations...\n";
16 25
 while(<>) {
17 26
     if(/malloc @(0x[0-9a-z]+) size (\d+) \((.*)\)/) {
18 27
 	die "ptr $1 re-malloc" if defined $ptrs{$1};
19 28
 	$ptrs{$1} = $2;
20
-	$sizes{$ptrs{$1}} = [0, 0, ''] unless defined $sizes{$ptrs{$1}};
29
+	$sizes{$ptrs{$1}} = [0, 0, 0, 'UNUSED'] unless defined $sizes{$ptrs{$1}};
30
+	$maxes{$ptrs{$1}} = [0, 0] unless defined $maxes{$ptrs{$1}};
31
+	$maxes{$ptrs{$1}}[0]++;
32
+	$maxes{$ptrs{$1}}[1] = $maxes{$ptrs{$1}}[0] unless $maxes{$ptrs{$1}}[1] >= $maxes{$ptrs{$1}}[0];
21 33
 	$maxsz = $2 unless $maxsz >= $2;
22 34
 	$overhead++ if $3 eq 'new map';
23 35
 	next;
24 36
     }
25 37
     if(/free @(0x[0-9a-z]+)/) {
26 38
 	die "ptr $1 invalid free" unless defined $ptrs{$1};
27
-	$sizes{$ptrs{$1}}[0]++;
39
+	$sizes{$ptrs{$1}}[TEMP]++;
40
+	$maxes{$ptrs{$1}}[0]--;
28 41
 	delete $ptrs{$1};
29 42
 	next;
30 43
     }
... ...
@@ -37,10 +50,13 @@ while(<>) {
37 37
 }
38 38
 
39 39
 $overhead *= $sizeof_void_ptr;
40
+print STDERR "Parsing complete (size overhead = $overhead)\n";
40 41
 
41
-foreach (keys %ptrs) {
42
-    $sizes{$ptrs{$_}}[1]++;
43
-}
42
+$sizes{$ptrs{$_}}[PERM]++ foreach (keys %ptrs);
43
+undef %ptrs;
44
+
45
+$sizes{$_}[MAXA] = $maxes{$_}[1] foreach (keys %maxes);
46
+undef %maxes;
44 47
 
45 48
 $maxsz |= $maxsz>>16;
46 49
 $maxsz |= $maxsz>>8;
... ...
@@ -50,31 +66,69 @@ $maxsz |= $maxsz>>1;
50 50
 $maxsz++;
51 51
 
52 52
 while($maxsz) {
53
+    my $nextsz = $maxsz>>1;
53 54
     if(defined $sizes{$maxsz}) {
54
-	$sizes{$maxsz}[2] = 'POW2';
55
+	$sizes{$maxsz}[REAS] = 'POW2';
55 56
     } else {
56
-	$sizes{$maxsz} = [0, 0, 'POW2'];
57
+	$sizes{$maxsz} = [0, 0, 0, 'POW2'];
57 58
     }
58
-    $maxsz>>=1;
59
-}
60
-
61
-my $grp_size = 0;
62
-foreach (sort { $b <=> $a } keys %sizes) {
63
-    my $count = $sizes{$_}[1];
64
-    my $score = ($grp_size - $_) * $count - $overhead;
65
-    $score = 0 unless $grp_size != 0;
59
+    my $nextpow2 = $nextsz;
60
+    while(1) {
61
+	my $refsz = $maxsz;
62
+	my @group;
63
+	foreach (sort { $b <=> $a } keys %sizes) {
64
+	    next unless $_ > $nextpow2;
65
+	    next unless $_ <= $maxsz;
66
+	    next unless ($sizes{$_}[TAKE] > 0 || $_ == $maxsz);
67
+	    $nextsz = $_;
68
+	    last unless ($refsz - $_) * $sizes{$_}[TAKE] <= $overhead;
69
+	    $refsz = $_;
70
+	    push @group, $_;
71
+	}
72
+	while($#group >= 23) {
73
+	    my $items = $#group / 2;
74
+	    $nextsz = $group[$items + 1];
75
+	    @group = @group[0..$items];
76
+	}
77
+	print STDERR "Processing group $maxsz -> $nextsz (count ".($#group + 1).")\n";
78
+	my @topscore; # 0 => score | 1 => used bits | origbits
79
+	for(my $origbits = 0; $origbits < 1<<$#group ; $origbits++) {
80
+	    my $bits = $origbits;
81
+	    my $bitcnt = 0;
82
+	    my $score = $overhead;
83
+	    my $grp_size = $maxsz;
66 84
 
67
-    if($score >= 0 || $sizes{$_}[2] eq 'POW2') {
68
-	$grp_size = $_;
69
-	if($score >=0) {
70
-	    $sizes{$_}[2] = $sizes{$_}[2] eq 'POW2' ? 'USE/POW2' : 'USE';
85
+	    printf STDERR "%3i%%\r", $origbits * 100 / (1<<$#group) unless ($origbits & 1);
86
+	    for (my $i = 1; $i<= $#group; $i++) {
87
+		if($bits & 1) {
88
+		    $score +=  $overhead + $sizes{$group[$i]}[TAKE] * $group[$i];
89
+		    $bitcnt++;
90
+		    $grp_size = $group[$i];
91
+		} else {
92
+		    $score += $sizes{$group[$i]}[TAKE] * $grp_size;
93
+		}
94
+		$bits>>=1;
95
+	    }
96
+	    if(!defined $topscore[0] || $score < $topscore[0] || ($score == $topscore[0] && $bitcnt > $topscore[1])) {
97
+		@topscore = ($score, $bitcnt, $origbits);
98
+	    }
71 99
 	}
72
-    } else {
73
-	$sizes{$_}[2] = 'GROUP';
100
+	my $bits = ($topscore[2]<<1) | 1;
101
+	for (my $i = 0; $i<=$#group; $i++) {
102
+	    if ($bits & 1) {
103
+		$sizes{$group[$i]}[REAS] = "USE";
104
+	    } else {
105
+		$sizes{$group[$i]}[REAS] = "GROUP";
106
+	    }
107
+	    $bits>>=1;
108
+	}
109
+	last unless $nextsz < $maxsz;
110
+	$maxsz = $nextsz;
74 111
     }
112
+    $maxsz = $nextpow2;
75 113
 }
76 114
 
77
-print "/* SIZE        PERM    TEMP    ACT! */\n";
115
+print "/* SIZE        PERM    TEMP     MAX    ACT! */\n";
78 116
 foreach (sort { $a <=> $b } keys %sizes) {
79
-    printf "%7u, /* %7u %7u %8s */\n", $_, $sizes{$_}[1], $sizes{$_}[0], $sizes{$_}[2];
117
+    printf "%7u, /* %7u %7u %7u %8s */\n", $_, $sizes{$_}[PERM], $sizes{$_}[TEMP], $sizes{$_}[MAXA], $sizes{$_}[REAS];
80 118
 }