pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
825 stars 131 forks source link

Performance degradation with Pygame 2.0.0 and 2.1.0 on Raspberry Pi (2883) #1469

Open GalacticEmperor1 opened 1 year ago

GalacticEmperor1 commented 1 year ago

Issue №2883 opened by salem-ok at 2021-12-04 11:18:05

Environment:

You can get some of this info from the text that pops up in the console when you run a pygame program.

Current behavior: My game runs at 18 FPS on average with pygame 2.0.0 and 2.1.0

Expected behavior:

My game runs at 30 FPS on average with pygame 1.9.4

Screenshots

N/A

Steps to reproduce:

Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. if the bug is caused by a specific file (image, font, sound, level, please upload it as an attachment

  1. Clone my repository https://github.com/salem-ok/PySprint.git
  2. run pysprint.py with various versions of pygame on a Raspberry Pi 4 running Buster
  3. Check the FPS counter at bottom right during a race

Comments

*MyreMylar commented at 2021-12-04 12:07:32*

Try switching to the SDL 2 blitter with the environment variable. If you get no visual artefacts in your game you are golden.

On Sat, 4 Dec 2021, 11:18 salem-ok, @.***> wrote:

Environment:

You can get some of this info from the text that pops up in the console when you run a pygame program.

  • Operating system: Raspbian GNU/Linux 10 (buster)
  • Python version : 3.7.3
  • SDL version : 2.0.0
  • PyGame version: 2.0.0 same issue reproduced on 2.1.0
  • Relevant hardware : Raspberry Pi 4 4Gb RAM

Current behavior: My game runs at 18 FPS on average with pygame 2.0.0 and 2.1.0

Expected behavior:

My game runs at 30 FPS on average with pygame 1.9.4

Screenshots

N/A

Steps to reproduce:

Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. if the bug is caused by a specific file (image, font, sound, level, please upload it as an attachment

  1. Clone my repository https://github.com/salem-ok/PySprint.git
  2. run pysprint.py with various versions of pygame on a Raspberry Pi 4 running Buster
  3. Check the FPS counter at bottom right during a race

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pygame/pygame/issues/2883, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGDGGXMQDSIWIMCA4NWCZLUPH2HVANCNFSM5JLO3NHA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.


*MyreMylar commented at 2021-12-04 12:11:31*

This variable is the one I mean:

PYGAME_BLEND_ALPHA_SDL2

It has some visual differences with the pygame 1/default blitter, but many users won't notice.

Docs on pygame env variables are here: https://www.pygame.org/docs/ref/pygame.html

On Sat, 4 Dec 2021, 12:07 Dan Lawrence, @.***> wrote:

Try switching to the SDL 2 blitter with the environment variable. If you get no visual artefacts in your game you are golden.

On Sat, 4 Dec 2021, 11:18 salem-ok, @.***> wrote:

Environment:

You can get some of this info from the text that pops up in the console when you run a pygame program.

  • Operating system: Raspbian GNU/Linux 10 (buster)
  • Python version : 3.7.3
  • SDL version : 2.0.0
  • PyGame version: 2.0.0 same issue reproduced on 2.1.0
  • Relevant hardware : Raspberry Pi 4 4Gb RAM

Current behavior: My game runs at 18 FPS on average with pygame 2.0.0 and 2.1.0

Expected behavior:

My game runs at 30 FPS on average with pygame 1.9.4

Screenshots

N/A

Steps to reproduce:

Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. if the bug is caused by a specific file (image, font, sound, level, please upload it as an attachment

  1. Clone my repository https://github.com/salem-ok/PySprint.git
  2. run pysprint.py with various versions of pygame on a Raspberry Pi 4 running Buster
  3. Check the FPS counter at bottom right during a race

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pygame/pygame/issues/2883, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGDGGXMQDSIWIMCA4NWCZLUPH2HVANCNFSM5JLO3NHA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.


*ankith26 commented at 2021-12-05 06:50:51*

hmm, while the new blitter might be responsible for some of the slowdown on the pi (due to the fact that neon optimisations are disabled by default), I don't think it fully accounts for the slowdown on the pi, there might be more stuff that causes this performance degrade. I will do some benchmarking and profiling on my pi later and post my findings here


*ankith26 commented at 2021-12-05 13:19:56*

Ok, I've done some benchmarking and profiling on my pi3 that runs PiOS bullseye (latest) and the results are not-so-good for pygame. I used this game to benchmark pygame, but I believe most pygame apps on PiOS experience a significant slowdown. The game I am testing plays well without any struggle at 60 FPS on my windows laptop (the FPS is capped at 60 by the game). To test on the pi, I had to reduce the size of the game window to 360x480 to fit my display

On the pi

To investigate the reason for the slowdown and eliminate any other sources of potential slowdown, I profile the game (using pygame 2.1.0 at this point with pygame blitter at default without SIMD) and indeed, Surface.blit is the culpit. In a game that ran for 20 seconds, Surface.blit seems to run for 13.5 seconds, almost 2/3rds of the CPU time is spent blitting, which is quite a lot, no other function even comes close to this, the next most expensive function is display.flip which has a cumulative time of 3 ish seconds. Profiling the same game on windows shows that most of the time is spent with the CPU sleeping while capping the FPS at 60 in Clock.tick

image

Comparing time per call of Surface.blit, it is 2.156e-05 s on my windows laptop and 2.089e-03 s on the Pi, that's literally almost a 100x slowdown! And display.flip seems to be 10x slower on the Pi than windows


*MyreMylar commented at 2021-12-05 14:26:18*

There was a bit of memory jogging over on the discord in which we recalled that SDL disabled their arm SIMD blitters by default a while ago (2.0.14 maybe?), and they haven't been re-enabled again yet.

So, if you want the best Arm/Pi performance, and don't care about visual impacts/differences to non-arm, then you need to either:

a) build SDL 2 yourself on the Pi with the arm blitters enabled. b) find a sufficiently old version of SDL 2 that the SIMD blitters were still turned on.

then use the pygame environment variable PYGAME_BLEND_ALPHA_SDL2 to switch to using the SDL 2 blitter over the pygame default one.

You could also explore using pre-multiplied alpha-blending (flags=pygame.BLEND_PREMULTIPLIED on blits) in your application.

Relevant SDL PRs & issue here:

Arm SIMD blitters disabled: https://github.com/libsdl-org/SDL/commit/363fd52b41808e4d5ab1afbd248ffd79e6c95990

Ongoing work to re-enable them: https://github.com/libsdl-org/SDL/issues/4484

At least that should do it.

MyreMylar commented 11 months ago

I'd like to retest this again at some point now there is a new Raspberry Pi 5 coming out.

MyreMylar commented 3 months ago

OK, after some fiddling about I've retested this game (PySprint) on pygame 2.1.0, and then again on latest Pygame-ce 2.5.0 on a new Raspberry Pi 5.

I also tried to go back to 1.9.6 on python 3.7 to compare - but that won't seem to install from Wheels anymore on the Pi 5 even when I try to manually install a 3.7 wheel from piwheels, I'm guessing it is some kind of manylinux incompatibility. I get:

20240527_15h50m40s_grim

Anyway the good news is that pygame versions are faster across the board as 2.1.0 still runs PySprint at 50 FPS even on 2.1.0.

On latest pygame-ce the game now hits around 80FPS. I feel like this issue is pretty much resolved now with improvements in pygame-ce, SDL and the march of time on Raspberry Pi hardware.

oddbookworm commented 3 months ago

Someone reported on discord that pygame-ce 2.5.0 is still stupendously slow on Raspberry Pi Zero 2W. Here are the results provided

Python 3.11.2 on Bookworm (64 bit Raspian) with pygame 2.1.2   17 fps
Python 3.11.2 on Bookworm (64 bit Raspian) with pygame-ce 2.5.0 17 fps
Python 3.9.2 on Bullseye (32 bit Raspian) with pygame-ce 2.5.0 13 fps
Python 3.9.2 on Bullseye (32 bit Raspian) with pygame 1.9.6 145 fps

test script

import pygame

WIDTH,HEIGHT = 1920,1080

pygame.init()

#window = pygame.display.set_mode((WIDTH,HEIGHT), flags=pygame.FULLSCREEN | pygame.SCALED, vsync=1)
window = pygame.display.set_mode((WIDTH,HEIGHT))

pgclk = pygame.time.Clock()
done = False

myfont = pygame.font.SysFont('freesansbold',50)

while not done:

    pgclk.tick()

    frame_rate=f"{pgclk.get_fps():07.1f}"
    fr_surface = myfont.render(frame_rate, True, pygame.Color("white"))
    fr_rect = fr_surface.get_rect(center=(WIDTH//2,HEIGHT//2))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                done = True

    window.fill(pygame.Color("black"))
    window.blit(fr_surface,fr_rect)

    pygame.display.update()

pygame.quit()

I'm reopening for now to open up discussions on if this is

MyreMylar commented 3 months ago

I'd be curious how they built SDL to get those results.

IIRC pi zero has no desktop OS so they would need to rebuild SDL with support for the kmsdrm driver in recent versions of Pygame and pygame-ce. Running the default Wayland or x11 drivers will be much slower or will behave oddly.

Back in the SDL1 days of Pygame 1.9.6 SDL used to have a specific rpi driver that shipped by default on the early pis and it raspberry pi assembly in the blitters at one point which may have made some difference.

Anyway, afaict this test program passes almost all code over to SDL so SDL configuration is the most likely difference.

On Fri, 14 Jun 2024, 02:40 Andrew Coffey, @.***> wrote:

Someone reported on discord that pygame-ce 2.5.0 is still stupendously slow on Raspberry Pi Zero 2W. Here are the results provided

Python 3.11.2 on Bookworm (64 bit Raspian) with pygame 2.1.2 17 fps Python 3.11.2 on Bookworm (64 bit Raspian) with pygame-ce 2.5.0 17 fps Python 3.9.2 on Bullseye (32 bit Raspian) with pygame-ce 2.5.0 13 fps Python 3.9.2 on Bullseye (32 bit Raspian) with pygame 1.9.6 145 fps

test script

import pygame WIDTH,HEIGHT = 1920,1080 pygame.init()

window = pygame.display.set_mode((WIDTH,HEIGHT), flags=pygame.FULLSCREEN | pygame.SCALED, vsync=1)window = pygame.display.set_mode((WIDTH,HEIGHT))

pgclk = pygame.time.Clock()done = False myfont = pygame.font.SysFont('freesansbold',50) while not done:

pgclk.tick()

frame_rate=f"{pgclk.get_fps():07.1f}"
fr_surface = myfont.render(frame_rate, True, pygame.Color("white"))
fr_rect = fr_surface.get_rect(center=(WIDTH//2,HEIGHT//2))

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        done = True
    elif event.type == pygame.KEYDOWN:
        if event.key == pygame.K_q:
            done = True

window.fill(pygame.Color("black"))
window.blit(fr_surface,fr_rect)

pygame.display.update()

pygame.quit()

I'm reopening for now to open up discussions on if this is

  • [ ] something we can fix in the first place
  • [ ] something we want to fix if we can

— Reply to this email directly, view it on GitHub https://github.com/pygame-community/pygame-ce/issues/1469#issuecomment-2167056837, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGDGGXRMIF3MGVH5OTRKF3ZHJCZ3AVCNFSM6AAAAAAUZLYXQGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRXGA2TMOBTG4 . You are receiving this because you modified the open/close state.Message ID: @.***>

ankith26 commented 2 months ago

I would like to know how the performance changes if one tries disabling framebuffer acceleration by setting the environment variable to zero like SDL_FRAMEBUFFER_ACCELERATION=0 on a raspberry pi (preferably on an older one where the performance regression is very steep)