Skip to content

pypy, frame drops (430)ย #408

@GalacticEmperor1

Description

@GalacticEmperor1

Issue โ„–430 opened by illume at 2018-03-23 10:56:47

pypy has spikes in time it takes occasionally when using cpyext, otherwise known as pauses.

This is because it's deallocating lots of CPython objects all in one frame, rather than incrementally. This is likely to be addressed in a future release of pypy.

To work around it for now,

Below are timings of the default pygame, and default pypy (at time of writing). Then a benchmark showing the improvement with the rect freelist implemented in rect.c inside pygame. Then we also improve things by setting PYPY_GC_NURSERY=1m environment variable to change the behavior of the GC. I'm not aware of an API to do this within pygame itself unfortunately. Finally there are some cpython 3.6 timings for comparison.

hacked up benchmark.

The hacked up benchmark is in the branch pypy-hack-frame-bench of the pygame repo. It's based off examples.testsprite. Because pypy currently doesn't compile matplot lib you need to run it in two steps. First to do the run (let it run for 20+ seconds). Then to load the data pickle, and show the graph.


pypy examples/testsprite.py -plot -noupdate_rects -width 320 -height 200 100

python examples/testsprite.py -plotpickle

To run with the GC tweak...


PYPY_GC_NURSERY=1m pypy examples/testsprite.py -plot -noupdate_rects -width 320 -height 200 100

graph colors

  • Blue is the first 1200 frames

  • orange is the last 1200 frames of the run.

This is useful to see if there are any jit warm up affects happening, or different behaviour over time. (doesn't appear so).

Time per frame on pypy 5.10.0.

For this example we don't see any 'jit warm up' behavior.

screen shot 2018-03-23 at 07 21 05

Time per frame on pypy 5.10.0, rect freelist, standard GC.

screen shot 2018-03-23 at 12 05 42

Time per frame on pypy 5.10.0, rect freelist, PYPY_GC_NURSERY=1m.

screen shot 2018-03-23 at 12 04 42

This final result for pypy 'ok' because we want under 0.0166 seconds used per frame. Improvements inside pypy itself in the future should hope to remove many of these spikes.

Time per frame on python3.6

Here we see both the average time per frame and maximums are smaller on python3.6.

screen shot 2018-03-23 at 12 22 02

Time per frame on python3.6, rect freelist

It seems the freelist for rects on python3.6 has a minimal affect.

screen shot 2018-03-23 at 12 20 12

Time per frame on python3.6, gc.disable()

Here we can see using gc.disable() seems to have no affect in this program (on python 3.6). I also tried this on pypy, and it had no affect either (on this program).

screen shot 2018-03-23 at 12 25 14

Other things I tried was to do a gc.collect(0) just before display.flip(), however this didn't appear to help in this case. This is because we can know if we have 5-10ms free waiting for the display VSYNC to flip (when running at 60Hz). Perhaps this can be attempted again as the cpyext GC is improved.


Comments

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions