[pypy-dev] cpyext performance

Stefan Behnel stefan_ml at behnel.de
Tue Jul 3 11:33:16 CEST 2012


Hi,

I've been working with one of the modules in the Python benchmark suite,
namely nbody, and tried to make it run a little faster when compiled with
Cython in PyPy. I managed to get a massive speed-up by avoiding some
borrowed references during list iteration and using PySequence_GetItem()
instead, but now some 50-60% of the runtime are spent in Py_DecRef().

I tried debugging into it, but so far, all my attempts to get anything
useful out of PyPy or cpyext have failed.

I applied this obvious change

"""
diff -r 20258fbf10d0 pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py    Sun Jul 01 10:02:26 2012 +0200
+++ b/pypy/module/cpyext/pyobject.py    Tue Jul 03 11:18:22 2012 +0200
@@ -340,13 +340,13 @@
     if obj.c_ob_refcnt == 0:
         state = space.fromcache(RefcountState)
         ptr = rffi.cast(ADDR, obj)
-        if ptr not in state.py_objects_r2w:
+        try:
+            w_obj = state.py_objects_r2w.pop(ptr)
+        except KeyError:
             # this is a half-allocated object, lets call the deallocator
             # without modifying the r2w/w2r dicts
             _Py_Dealloc(space, obj)
         else:
-            w_obj = state.py_objects_r2w[ptr]
-            del state.py_objects_r2w[ptr]
             w_type = space.type(w_obj)
             if not w_type.is_cpytype():
                 _Py_Dealloc(space, obj)
"""

and it gave me a couple of percent, but beyond that, I'd have to know what
paths are actually taken here and where most of the time is spent.

Running it through callgrind yields nothing helpful, so I tried running it
in plain Python. That failed with an OverflowError in ll2ctypes.py:

"""
Traceback (most recent call last):
  File "pypy-1.9/pypy/bin/py.py", line 187, in <module>
    sys.exit(main_(sys.argv))
  File "pypy-1.9/pypy/bin/py.py", line 86, in main_
    space = option.make_objspace(config)
  File "pypy-1.9/pypy/tool/option.py", line 45, in make_objspace
    None, None, ['Space'])
  File "pypy-1.9/pypy/objspace/std/__init__.py", line 1, in <module>
    from pypy.objspace.std.objspace import StdObjSpace
  File "pypy-1.9/pypy/objspace/std/objspace.py", line 18, in <module>
    from pypy.objspace.std.complexobject import W_ComplexObject
  File "pypy-1.9/pypy/objspace/std/complexobject.py", line 6, in <module>
    from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
  File "pypy-1.9/pypy/objspace/std/floatobject.py", line 48, in <module>
    class W_FloatObject(W_AbstractFloatObject):
  File "pypy-1.9/pypy/objspace/std/floatobject.py", line 51, in W_FloatObject
    from pypy.objspace.std.floattype import float_typedef as typedef
  File "pypy-1.9/pypy/objspace/std/floattype.py", line 87, in <module>
    _double_format, _float_format = detect_floatformat()
  File "pypy-1.9/pypy/objspace/std/floattype.py", line 64, in
detect_floatformat
    rffi.cast(rffi.DOUBLEP, buf)[0] = 9006104071832581.0
  File "pypy-1.9/pypy/rpython/lltypesystem/lltype.py", line 1219, in
__setitem__
    self._obj.setitem(i, val)
  File "pypy-1.9/pypy/rpython/lltypesystem/ll2ctypes.py", line 620, in setitem
    self._storage.contents._setitem(index, value, boundscheck=False)
  File "pypy-1.9/pypy/rpython/lltypesystem/ll2ctypes.py", line 279, in _setitem
    items = self._indexable(index)
  File "pypy-1.9/pypy/rpython/lltypesystem/ll2ctypes.py", line 259, in
_indexable
    PtrType = self._get_ptrtype()
  File "pypy-1.9/pypy/rpython/lltypesystem/ll2ctypes.py", line 255, in
_get_ptrtype
    raise e
OverflowError: array too large
"""

No idea what this is supposed to tell me, except that I apparently hit yet
another bug in PyPy.

Now, having wasted enough time with this, I'd be happy if someone else
could take over. I put the C code here that I used:

http://cython.org/nbodybench.tar.bz2

You can build it without Cython, just run the included setupdu.py script
over it and call

    pypy -c 'import nbody; print(nbody.test_nbody(1))'

Then try to profile that.

Stefan



More information about the pypy-dev mailing list