Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the use of porting::getTimeMs() when rendering frames #12679

Merged
merged 5 commits into from
Aug 13, 2022

Conversation

x2048
Copy link
Contributor

@x2048 x2048 commented Aug 9, 2022

Optimization is based on this graph from hotspot:
image

  1. Remove excessive calls to TimeTaker in renderMap() and renderMapShadow()
  2. Centralize clock time per frame in ClientEnvironment and avoid calling porting::getTimeMs() from shader constant setters.

To do

This PR is Ready for Review.

How to test

  1. Start any game
  2. FPS should be higher, and rendering should be correct.

@rubenwardy
Copy link
Member

Do you get a higher FPS with this? Interested to know if there's a visible difference

@Desour
Copy link
Member

Desour commented Aug 10, 2022

Tested using quicktune: Desour@3f9c3c2
I've seen no difference on my machine.

@x2048
Copy link
Contributor Author

x2048 commented Aug 10, 2022

@Desour updateFrameTime() is the optimized method, can you try to quicktune on master?

The difference for me is from 37 to 47 FPS in a similar scene in the same location in a RelWithDebInfo build:
Screenshot_20220810_181729

Screenshot_20220810_181914


void ClientEnvironment::updateFrameTime()
{
m_frame_time = porting::getTimeMs();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be the best location to remind contributors of the purpose of this function.

Suggested change
m_frame_time = porting::getTimeMs();
// Cache the time each frame to reduce time-consuming getTimeMs() calls for (semi-)debug builds.
m_frame_time = porting::getTimeMs();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also more correct to always use the same timestamp during rendering of a specific frame.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an added bonus :)

@Desour
Copy link
Member

Desour commented Aug 10, 2022

@Desour updateFrameTime() is the optimized method, can you try to quicktune on master?

I'm not sure what you mean with "quicktune on master".
I've used minetest's quicktune thing to toggle the optimisation on and off in-game (i.e. make getFrameTime call porting::getTimeMs or just return the cached value).

I've used a Release build, not RelWithDebInfo. Idk if that makes a difference.

@sfan5
Copy link
Member

sfan5 commented Aug 10, 2022

I'm all for reducing useless calls but isn't clock_gettime supposed to be very fast? It goes via vdso on Linux.

src/client/clientmap.cpp Outdated Show resolved Hide resolved
@x2048
Copy link
Contributor Author

x2048 commented Aug 10, 2022

Clean release builds show even bigger difference between the branches:
Screenshot_20220810_221028
Screenshot_20220810_221146

@sfan5 If my math is right, we were calling getTimeMs() 200K times a second (without shadow mapping) at 33 FPS. Apparently, clock_gettime is not that fast, at least on my Ubuntu kernel.

Copy link
Member

@sfan5 sfan5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works but the improvement is tiny on my machine.

@x2048 x2048 merged commit d1cbb4b into minetest:master Aug 13, 2022
@x2048 x2048 deleted the optimize branch August 13, 2022 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants