[pypy-svn] r58223 - in pypy/build/benchmem: . testing

hpk at codespeak.net hpk at codespeak.net
Thu Sep 18 15:17:21 CEST 2008


Author: hpk
Date: Thu Sep 18 15:17:19 2008
New Revision: 58223

Modified:
   pypy/build/benchmem/benchtool.py
   pypy/build/benchmem/testing/test_benchtool.py
Log:
(intermediate) advancing the tool to run commandlines like "python benchtool.py python2.5 create_recursive_tuples.py"


Modified: pypy/build/benchmem/benchtool.py
==============================================================================
--- pypy/build/benchmem/benchtool.py	(original)
+++ pypy/build/benchmem/benchtool.py	Thu Sep 18 15:17:19 2008
@@ -32,7 +32,9 @@
                 pid = os.getpid()
                 sys.stdout.write(str(pid))
                 sys.stdout.write("\\n")
+                checkpoint()
                 %s(checkpoint, %s)
+                checkpoint()
         """ %(name, arglist))
         p = self.resultdir.join("%s.py" %(name,)) 
         p.write(source)
@@ -68,7 +70,6 @@
         self.pid = pid
         self.smapspath = py.path.local("/proc/%d/smaps" %(pid,))
         assert self.smapspath.check()
-        self.snapshot()
 
     def snapshot(self):
         s = self.smapspath.read()
@@ -77,13 +78,33 @@
         self._file.write(self.SEPLINE)
         self._file.flush()
 
+class SmapsReader:
+    def __init__(self, snapshots):
+        self.snapshots = snapshots
+
+    @classmethod
+    def parse(cls, path):
+        """ parse a file previously recorded through SmapsRecorder. """
+        s = path.read()
+        parts = filter(None, map(str.strip, s.split(SmapsRecorder.SEPLINE)))
+        snapshots = [SmapsProcess.parse(s) for s in parts]
+        return cls(snapshots)
+
+    def _verify_integrity(self):
+        for snap in self.snapshots:
+            for mapping in snap.mappings:
+                clean = mapping.shared_clean + mapping.private_clean 
+                dirty = mapping.private_dirty + mapping.shared_dirty 
+                assert mapping.rss == dirty + clean
+        
+
 class SmapsMapping:
     def __init__(self, headvars, bodyvars):
         self.__dict__.update(headvars)
         self.__dict__.update(bodyvars)
         self.inode = int(self.inode)
     
-class SmapsReader(object):
+class SmapsProcess(object):
     # example '402c1000-402c2000 rw-p 00011000 1f:04 1110 /lib/libnsl-2.5.so'
     headrex = re.compile(r"""
           (?P<virtualaddress>\w+-\w+)\s+
@@ -98,10 +119,14 @@
 
     def __init__(self, mappings):
         self.mappings = mappings
+        self.UNIT = "kB"
         for name in ("size rss shared_clean shared_dirty "
                      "private_clean private_dirty".split()):
             setattr(self, name, sum([getattr(x, name) for x in mappings]))
-        
+
+    def memusage(self):
+        return "privdirty: %d, shadirty: %d" %(self.private_dirty, self.shared_dirty)
+
     @classmethod
     def parse(cls, string):
         lines = string.split("\n")
@@ -125,7 +150,7 @@
                     break
                 name, num = m.groups()
                 name = name.lower()
-                num = int(num) * 1024 # xxx get constant from somewhere? 
+                num = int(num) 
                 assert name not in bodyvars
                 bodyvars[name] = num
             else:
@@ -133,5 +158,23 @@
         return cls(mappings)
              
 if __name__ == '__main__':
-    pass
-
+    executable = sys.argv[1]
+    name = sys.argv[2]
+    resultdir = py.path.local("resultdir").ensure(dir=1)
+    print "using", resultdir
+    benchrunner = BenchRunner(executable, resultdir)
+    logpath = benchrunner.run_checkpointed_bench(name, (100, 1000))
+    reader = SmapsReader.parse(logpath)
+    last = None
+    for i, snap in enumerate(reader.snapshots):
+        if last is None:
+            last = snap
+            print i, snap.memusage()
+            continue
+        if (last.private_dirty != snap.private_dirty or 
+            last.shared_dirty != snap.shared_dirty or 
+            len(last.mappings) != snap.mappings):
+            print i, snap.memusage()#, snap.memdiff(last)
+    else:
+            print i, snap.memusage()#, snap.memdiff(last)
+    

Modified: pypy/build/benchmem/testing/test_benchtool.py
==============================================================================
--- pypy/build/benchmem/testing/test_benchtool.py	(original)
+++ pypy/build/benchmem/testing/test_benchtool.py	Thu Sep 18 15:17:19 2008
@@ -13,25 +13,28 @@
     pid = os.getpid()
     rec = benchtool.SmapsRecorder(pid=pid, logpath=logpath)
     s = logpath.read()
-    assert s.count(benchtool.SmapsRecorder.SEPLINE) == 1
+    assert s.count(benchtool.SmapsRecorder.SEPLINE) == 0
     rec.snapshot()
     rec.snapshot()
     del rec
     s = logpath.read()
-    assert s.count(benchtool.SmapsRecorder.SEPLINE) == 3
+    assert s.count(benchtool.SmapsRecorder.SEPLINE) == 2
 
-def test_benchrunner():
+def test_benchrunner_functional():
     tmpdir = py.test.ensuretemp("benchrunner")
     runner = benchtool.BenchRunner(executable="python2.5", resultdir=tmpdir)
     def checker(name, *args):
         smapsfile = runner.run_checkpointed_bench(name, args)
         assert smapsfile.check()
+        reader = benchtool.SmapsReader.parse(smapsfile)
+        assert len(reader.snapshots) == 10 + 2
+        reader._verify_integrity()
 
     for name in benchtool.benchmarkdir.listdir("*.py"):
         if name.basename[0] != "_": 
             yield checker, name.basename, 10, 10
 
-class TestSmapsReader:
+class TestSmapsProcess:
     def setup_class(cls):
         cls.s = py.std.textwrap.dedent("""\
             08048000-0813f000 r-xp 00000000 fd:00 75457      sometext
@@ -50,7 +53,7 @@
             Private_Dirty:        8 kB""")
 
     def test_parse_mappings(self):
-        smapsreader = benchtool.SmapsReader.parse(self.s)
+        smapsreader = benchtool.SmapsProcess.parse(self.s)
         mappings = smapsreader.mappings
         assert len(mappings) == 2
         mapping = mappings[0]
@@ -59,11 +62,11 @@
         assert mapping.dev == "fd:00"
         assert mapping.inode == 75457
         assert mapping.filename == "sometext"
-        assert mapping.size == 988 * 1024 
-        assert mapping.rss == 796 * 1024 
+        assert mapping.size == 988 
+        assert mapping.rss == 796 
         assert mapping.shared_clean == 0
         assert mapping.shared_dirty == 0
-        assert mapping.private_clean == 796 * 1024
+        assert mapping.private_clean == 796 
         assert mapping.private_dirty == 0
         #assert mapping.referenced is None
 
@@ -73,16 +76,16 @@
         assert mapping.dev == "00:00"
         assert mapping.inode == 0
         assert not mapping.filename
-        assert mapping.size == 16 * 1024 
-        assert mapping.rss == 8 * 1024
+        assert mapping.size == 16 
+        assert mapping.rss == 8 
         assert mapping.shared_clean == 0
         assert mapping.shared_dirty == 0
         assert mapping.private_clean == 0
-        assert mapping.private_dirty == 8 * 1024
-        #assert mapping.referenced == 12 * 1024
+        assert mapping.private_dirty == 8 
+        #assert mapping.referenced == 12 
 
     def test_summing(self):
-        smaps = benchtool.SmapsReader.parse(self.s)
+        smaps = benchtool.SmapsProcess.parse(self.s)
         for name in ('size rss shared_clean shared_dirty '
                      'private_clean private_dirty').split():
             sumval = getattr(smaps, name)



More information about the Pypy-commit mailing list