Re: [pygame] pygame.display.flip slow

2020-02-24 Thread Nuno Maltez
Hi,

Thanks again for the answers.

Both machines are running Fedora Linux. Both are using X11 and the nvidia
drivers, but the drivers are different versions (older graphics card in
machine B).

I'll look at the settings to see if I can figure out the difference.
I'll try to find out

On Thu, Feb 20, 2020 at 10:30 PM Greg Ewing 
wrote:

> On 20/02/20 8:57 am, Nuno Maltez wrote:
> > when I run my test program, Machine B reports FPS > 200, and
> > pygame.display.flip taking 0.002 per call,
> > while machine A reports FPS < 60, and pygame.display.flip taking 0.016
> > per call.
>
> This looks to me like machine A is synchronising its flips
> with the monitor's refresh rate, but machine B is not. Why
> that would be when you're creating the surface with the same
> flags I don't know. Maybe a difference in the display
> driver?
>
> --
> Greg
>


Re: [pygame] pygame.display.flip slow

2020-02-20 Thread Greg Ewing

On 20/02/20 8:57 am, Nuno Maltez wrote:
when I run my test program, Machine B reports FPS > 200, and 
pygame.display.flip taking 0.002 per call,
while machine A reports FPS < 60, and pygame.display.flip taking 0.016 
per call.


This looks to me like machine A is synchronising its flips
with the monitor's refresh rate, but machine B is not. Why
that would be when you're creating the surface with the same
flags I don't know. Maybe a difference in the display
driver?

--
Greg


Re: [pygame] pygame.display.flip slow

2020-02-20 Thread Ian Mallett
Hi,

To me, these results suggest that the faster-framerate machine is running
with VSync enabled for some reason and the slower-framerate machine is
running without. Also, what I said about setting pixels on the CPU still
goes, albeit that's not the issue here.

Offhand, I would guess that the faster-framerate machine is running
Windows, which doesn't enable VSync, and the slower-framerate machine is
running something else. But I don't know.

In general, faster framerates are pointless (you can't even display them),
so one should be satisfied with ~60Hz refresh, and make the logic
independent of timestep (locking the framerate to the refresh rate is a
*good* thing; the fascination with faster framerates is due to modern video
games running <60Hz, or to gamers running >60Hz with tearing (and without
VSync).). There are platform-specific ways to disable VSync. It's not even
that hard for OpenGL contexts. But it's sortof an X-Y problem that doesn't
need solving.

Ian


Re: [pygame] pygame.display.flip slow

2020-02-19 Thread Nuno Maltez
Hi,

Thanks for the quick feedback, and apologies if my little program caused
some confusion - I wrote it quickly to highlight an issue, but I guess I
should have included some results from another machine for comparison.

I made some improvements based on Ian's suggestions:

1. I don't average anything, just output the recorded fps values
2. I removed the argument to tick() - this actually helps to showcase the
issue

I ran the code (pasted below) on two machines:

Machine A:
Intel(R) Core(TM) i7-5930K CPU @ 3.50GHz
Python 3.7, Pygame1.9.6

Machine B:
Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz
Python 3.7, Pygame1.9.6

The first benchmark on google results shows A should be significantly
faster than B
https://cpu.userbenchmark.com/Compare/Intel-Core-i7-4650U-vs-Intel-Core-i7-5930K/m6364vs2578

I ran pyperformance (
https://pyperformance.readthedocs.io/usage.html#installation) on both
machines and it seems to confirm that.

However, when I run my test program, Machine B reports FPS > 200, and
pygame.display.flip taking 0.002 per call,
while machine A reports FPS < 60, and pygame.display.flip taking 0.016 per
call.

This puzzles me: I was expecting a result similar to B on both machines,
since my loop does nothing - has no game logic, no physics, no image
handling. I was wondering if someone has any ideas to help me find out
what's wrong with
my setup in machine A. Btw, enabling fullscreen does not help, not does
changing the display resolution while
running in the windowed mode. Both displays are running at 60Hz.

MAchine A:
$ python fps_test.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html


[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 54.64480972290039,
54.64480972290039, 54.64480972290039, 54.64480972290039, 54.64480972290039,
54.64480972290039, 54.64480972290039, 54.64480972290039, 54.64480972290039,
54.64480972290039, 57.47126770019531, 57.47126770019531, 57.47126770019531,
57.47126770019531, 57.47126770019531, 57.47126770019531, 57.47126770019531,
57.47126770019531, 57.47126770019531, 57.47126770019531, 58.82352828979492,
58.82352828979492, 58.82352828979492, 58.82352828979492, 58.82352828979492,
58.82352828979492, 58.82352828979492, 58.82352828979492, 58.82352828979492,
58.82352828979492, 59.52381134033203, 59.52381134033203, 59.52381134033203,
59.52381134033203, 59.52381134033203, 59.52381134033203, 59.52381134033203,
59.52381134033203, 59.52381134033203, 59.52381134033203, 59.88024139404297,
59.88024139404297, 59.88024139404297, 59.88024139404297, 59.88024139404297,
59.88024139404297, 59.88024139404297, 59.88024139404297, 59.88024139404297,
59.88024139404297, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 58.479530334472656, 58.479530334472656,
58.479530334472656, 59.17159652709961, 59.17159652709961,
59.17159652709961, 59.17159652709961, 59.17159652709961, 59.17159652709961,
59.17159652709961, 59.17159652709961, 59.17159652709961, 59.17159652709961]
 405 function calls in 1.760 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
10.0000.0001.7601.760 :1()
10.0020.0021.7601.760 fps_test.py:11(run)
10.0000.0001.7601.760 {built-in method
builtins.exec}
10.0000.0000.0000.000 {built-in method
builtins.print}
  1001.6440.0161.6440.016 {built-in method
pygame.display.flip}
10.0000.0000.0000.000 {method 'disable' of
'_lsprof.Profiler' objects}
  1000.1140.0010.1140.001 {method 'fill' of
'pygame.Surface' objects}
  1000.0000.0000.0000.000 {method 'get_fps' of 'Clock'
objects}
  1000.0000.0000.0000.000 {method 'tick' of 'Clock'
objects}



Machine B:

$ python fps_test.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html


[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 256.4102478027344,
256.4102478027344, 256.4102478027344, 256.4102478027344, 256.4102478027344,
256.4102478027344, 256.4102478027344, 256.4102478027344, 256.4102478027344,
256.4102478027344, 263.15789794921875, 263.15789794921875,
263.15789794921875, 263.15789794921875, 263.15789794921875,
263.15789794921875, 263.15789794921875, 263.15789794921875,
263.15789794921875, 263.15789794921875, 303.0303039550781,
303.0303039550781, 303.0303039550781, 303.0303039550781, 303.0303039550781,
303.0303039550781, 303.0303039550781,

Re: [pygame] pygame.display.flip slow

2020-02-18 Thread Ian Mallett
Hi,

First, there are some problems with this test code:

- The first ten framerates will be 0.0 due to what I consider a misfeature
in the way pygame reports framerate; this drags down your average. Even if
you ran at a nominal 60Hz, the highest reported framerate is going to be
54fps (wherefore, I'm somewhat confused that you say you got 60Hz on a
different machine; perhaps you were running a bit faster; e.g. I see 62Hz a
lot on certain machines).

- Averaging the framerates is a bit problematic because that is a
reciprocal measure. It is better to average the frame latencies and then
reciprocate that to get the average framerate.

- You're attempting to synchronize the framerate to 60Hz, this can cause
aliasing issues since pygame is software-backed, not graphics backed,
exactly. E.g., if your code is actually 59fps, then the fastest it can
update will be 30fps. It would be better to not include the argument to
`.tick(...)` at all.

Which brings us to the main reason:

- Setting millions of pixels is not a job for the CPU; it's a job for the
graphics card. However, pygame runs on the CPU. As you observe, larger
displays run slower. If you want good refresh-bound performance, you
probably want to make a GL context and draw with that, without disabling
VSync. This is, in fact, what glxgears does, which is why it's running at a
reasonable framerate.

Ian


Re: [pygame] pygame.display.flip slow

2020-02-18 Thread mar77i


‐‐‐ Original Message ‐‐‐
On Tuesday, February 18, 2020 3:50 PM, Nuno Maltez  wrote:

> Hi
> I'm experiencing very slow frame rates on a particular set up and need some 
> help to understand
> what may be causing it.
> On this machine, the code below has an avg fram rate of around 45fps.
> The profiling output is:
>
>    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
>         1    0.000    0.000    2.015    2.015 :1()
>         1    0.001    0.001    2.015    2.015 fps_test.py:11(run)
>         1    0.000    0.000    2.015    2.015 {built-in method builtins.exec}
>         1    0.000    0.000    0.000    0.000 {built-in method builtins.print}
>         1    0.000    0.000    0.000    0.000 {built-in method builtins.sum}
>       100    1.977    0.020    1.977    0.020 {built-in method 
> pygame.display.flip}
>         1    0.000    0.000    0.000    0.000 {method 'disable' of 
> '_lsprof.Profiler' objects}
>       100    0.031    0.000    0.031    0.000 {method 'fill' of 
> 'pygame.Surface' objects}
>       100    0.000    0.000    0.000    0.000 {method 'get_fps' of 'Clock' 
> objects}
>       100    0.006    0.000    0.006    0.000 {method 'tick' of 'Clock' 
> objects}
> This is:
> Fedora 31
> Python 3.7.6
> Pygame 1.9.6 (I tried pygame 2.0.0.dev7 and it's the same)


Takes beautifully the 20 milliseconds you'd expect for a 50 Hz display. Use 
pygame.display.update() if you want to take care of the framerate yourself. :)

cheers!
mar77i



Sent with ProtonMail Secure Email.



[pygame] pygame.display.flip slow

2020-02-18 Thread Nuno Maltez
Hi

I'm experiencing very slow frame rates on a particular set up and need some
help to understand
what may be causing it.

On this machine, the code below has an avg fram rate of around 45fps.
The profiling output is:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
10.0000.0002.0152.015 :1()
10.0010.0012.0152.015 fps_test.py:11(run)
10.0000.0002.0152.015 {built-in method
builtins.exec}
10.0000.0000.0000.000 {built-in method
builtins.print}
10.0000.0000.0000.000 {built-in method builtins.sum}
  1001.9770.0201.9770.020 {built-in method
pygame.display.flip}
10.0000.0000.0000.000 {method 'disable' of
'_lsprof.Profiler' objects}
  1000.0310.0000.0310.000 {method 'fill' of
'pygame.Surface' objects}
  1000.0000.0000.0000.000 {method 'get_fps' of 'Clock'
objects}
  1000.0060.0000.0060.000 {method 'tick' of 'Clock'
objects}

This is:
Fedora 31
Python 3.7.6
Pygame 1.9.6 (I tried pygame 2.0.0.dev7 and it's the same)

The specs are fine:
Intel(R) Core(TM) i7-5930K CPU @ 3.50GHz

"glxgears" runs happily at 60fps on this machine.
I can run the code below on a on slower machine (my laptop) with the same
software config
(F31/Python3.7/Pygame1.9.6)  and easily get the 60fps.

Any pointers to what may be causing this? Oh, a note, the larger the
display size,
the slower it gets. 1440x900 is just the size of the laptop screen, so the
larger I
could use to compare using the same version of Fedora.

import pygame
pygame.init()
clock = pygame.time.Clock()
screen_flags = 0
screen = pygame.display.set_mode((1440, 900), screen_flags)
pygame.display.set_caption("FPS Test")
print(pygame.display.Info())

def run():
x = 0
fps = [0] * 100
while x < 100:
screen.fill(pygame.Color(0, 0, 0))
pygame.display.flip()
clock.tick(60)
fps[x] = clock.get_fps()
x += 1
print(sum(fps)/100.)
import cProfile
cProfile.run('run()')


Thanks.