From d1168b493ac0b6295d45826c19634c7d784cd728 Mon Sep 17 00:00:00 2001 From: ehofman Date: Wed, 9 Mar 2005 15:12:01 +0000 Subject: [PATCH] Frederic Bouvier: Norman Vine wrote : > Frederic Bouvier writes: > >> Quoting Andy Ross: >>> * Hopefully in a CPU-friendly way. I know that older versions of >>> the NVidia drivers did this by spinning in a polling loop >>> inside the driver. I'm not sure if this has been fixed or not. >>> >>> From my experience, the latest non-beta Windows NVidia driver seems to eat CPU >> >> even with sync to vblank enabled. The CPU usage is always 100%. > > Buried in the PPE sources is a 'hackish' but portable way to limit CPU usage if the desired framerate is met > > /* > Frame Rate Limiter. > > This prevents any one 3D window from updating faster than > about 60Hz. This saves a ton of CPU time on fast machines. > > ! I THINK I MUNGED THE VALUE FOR ulMilliSecondSleep() NHV ! > */ > > static ulClock *ck = NULL ; > > if ( frame_rate_limiter ) > { > if ( ck == NULL ) > { > ck = new ulClock ; > ck -> update () ; > } > > int t_ms = (int) ( ck->getDeltaTime() * 1000.0 ) ; /* Convert to ms */ > > if ( t_ms < 16 ) > ulMilliSecondSleep ( 16 - t_ms ) ; > } > > I implemented the method pointed out by Norman. It works great on windows and saves me a lot of CPU cycles. This way, I can get the same framerate in moderately populated areas and have CPU idle 50% of the time instead of wildly looping in the NVidia driver while waiting to sync on vblank. It has been tested on Linux by Melchior. He saw the same gain in CPU cycles. --- src/Main/main.cxx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 83d3add39..db569b84e 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -222,6 +222,8 @@ static void fgMainLoop( void ) { SGCloudLayer::enable_bump_mapping = fgGetBool("/sim/rendering/bump-mapping"); + bool scenery_loaded = fgGetBool("sim/sceneryloaded") || fgGetBool("sim/sceneryloaded-override"); + // Update the elapsed time. static bool first_time = true; if ( first_time ) { @@ -230,13 +232,20 @@ static void fgMainLoop( void ) { } double throttle_hz = fgGetDouble("/sim/frame-rate-throttle-hz", 0.0); - if ( throttle_hz > 0.0 ) { + if ( throttle_hz > 0.0 && scenery_loaded ) { + static double remainder = 0.0; + // simple frame rate throttle - double dt = 1000000.0 / throttle_hz; + double dt = 1000000.0 / throttle_hz + remainder; + int wait = dt / 1000; + remainder = dt - ( wait * 1000.0 ); + current_time_stamp.stamp(); - while ( current_time_stamp - last_time_stamp < dt ) { - current_time_stamp.stamp(); + int t_ms = (int) ( ( current_time_stamp - last_time_stamp ) / 1000 ) ; /* Convert to ms */ + if ( t_ms < wait ) { + ulMilliSecondSleep ( wait - t_ms ) ; } + current_time_stamp.stamp(); } else { // run as fast as the app will go current_time_stamp.stamp(); @@ -421,8 +430,6 @@ static void fgMainLoop( void ) { remainder = 0; } - bool scenery_loaded = fgGetBool("sim/sceneryloaded") || fgGetBool("sim/sceneryloaded-override"); - // flight model if ( global_multi_loop > 0) { // first run the flight model each frame until it is intialized -- 2.39.5