Playing video or audio in other apps can cause an increase in pybullet simulation performance

Official Python bindings with a focus on reinforcement learning and robotics.
Post Reply
elkmug
Posts: 8
Joined: Fri Nov 10, 2017 7:05 pm

Playing video or audio in other apps can cause an increase in pybullet simulation performance

Post by elkmug »

Yeah, you read that right, an increase in simulation performance.

Initially this behavior appeared to be random. It happened frequently, but I had no idea why, and I could not reproduce the issue on demand.

After a lot of trial and error I can now reliably trigger this behavior with the web browser Waterfox and the video recording and live streaming app OBS Studio. Both of these programs have portable 64-bit versions which is what I use. I imagine that any modern web browser will work, but I do know that Internet Explorer 11 will not.

To display the behavior take a pybullet script and set the timeStep so that it's smaller than your system can play well. For me that's 1/1000.0 or anything under 1/100.0
  • In Waterfox, go to a page with video, for example youtube, load a video, after it starts playing pause it.
  • Run the pybullet script. The simulation should be very slow.
  • Now un-pause the video and the simulation performance will increase signifigantly.
    In my case 1/1000.0 with a video playing runs as well as or better than 1/100.0 without a video playing! I suppose it could be dropping frames, but it sure doesn't look like it to me. Toggling video playback on/off will toggle the performance increase on/off.
  • This also works with audio only, e.i. podcasts, played in Waterfox.
With OBS Studio, just having the app open triggers this behavior, maybe because it's window is "playing" the source even when it's not recording it. Which is kind of annoying because I wanted to record a video of the behavior. Now I'm like a guy who saw a unicorn saying "believe me":)

I'm really curious as to why this happening. Are the other apps somehow causing pybullet to run on the gpu or use more cpu threads?

Also, if this is a bug, please find a way to make it a feature or at least don't fix it.

Windows 7 64-bit sp1, geforce 750 Ti, nVidia driver 390.65,
WaterFox 56.0.2(64-bit), OBS Studio 20.1.3(64-bit)
pybullet compiled with and without numpy,
and for both Python 3.6.4 and 2.7.13

Sim parameters:

Code: Select all

p.setPhysicsEngineParameter(fixedTimeStep = timeStep, numSubSteps=1, numSolverIterations=10)
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Playing video or audio in other apps can cause an increase in pybullet simulation performance

Post by Erwin Coumans »

Heh, that is a very funny post.

You are using PyBullet using GUI connection? If so, there is some intra-thread communication happening, that involves some 'waiting' between threads. Likely, the OS behaves differently during those 'waits'. Try it again using DIRECT mode, it should run faster and independent on other apps.
elkmug
Posts: 8
Joined: Fri Nov 10, 2017 7:05 pm

Re: Playing video or audio in other apps can cause an increase in pybullet simulation performance

Post by elkmug »

Wow, Erwin's reply really sent me down a rabbit hole, but in a totally good way, because I actually found one pretty great rabbit down there :)

Long story short,(well, shorter than it was) the root cause of not being able use smaller time steps in win7 is how time.sleep() does what it does and win7 itself.

If you strip away everything except time.sleep() and test just it's performance the issue still happens. Some quality time with duckduckgo finally led to the reason; time.sleep() uses the operating system's sleep() function.

From https://www.pythoncentral.io/pythons-ti ... your-code/
Ultimately there are limitations to this function. For example on a standard Windows installation, the smallest interval you may sleep is 10-13 milliseconds. The Linux kernels tend to have a higher tick rate, where the intervals are generally closer to 1 millisecond.


The 10-13 milliseconds, tracks pretty much perfectly with my pybullet experience on win7. 1/100 works really well. At 1/130 the sim is visually a bit slower, but acceptable. Smaller than that things start to go progressively more slow-motion and floatly, and by 1/1000 have definitely become unusable. When tested on Linux (Mint 17 LTS) 1/1000 plays great. Smaller steps like 1/2000 and 1/5000 are completely usable and 1/10000, while slow-motion and floatly is much, much better than 1/1000 on win7.(And the video playback performance increase does not really happen on mint17 LTS)

Also note the quoted info is probably out of date. From what I've read newer versions of windows may have increased the precision of sleep() to 1 millisecond. I can't verify this since I don't have access to win10 or 8, but I've attached a python script for testing if anyone is curious. It should output a total time of roughly 1 second if the OS's sleep() has 1 millisecond precision or better.

Now we get to the rabbit, and the rabbit makes the entire issue moot, at least if you have python 3.3 or greater.

The rabbit's name is time.perf_counter(). Added in python 3.3, per the python docs it returns "the value (in fractional seconds) of a performance counter, i.e. a clock with the highest available resolution to measure a short duration. It does include time elapsed during sleep and is system-wide". Shorter, It uses the CPU's clock. The faster CPU the more precise the ticks.

Replacing

Code: Select all

p.stepSimulation()
time.sleep(timeStep)
with

Code: Select all

p.stepSimulation()
sleep = 1
cur = time.perf_counter()
while(sleep):
	if(time.perf_counter() >= cur + timeStep):
		sleep = 0
fixes, and in fact improves, everything. Video playback still effects things, but only by the slightest amount and isn't visually noticeable. Performance at 1/1000 is great. Performance at 1/10000 is visual almost as good. Performance at 1/50000 is a little slow-motion and a touch floatly but not too bad.

Like I said at the start, wow :)
Attachments
time_only_01.zip
(320 Bytes) Downloaded 308 times
Post Reply