Calculations on its own thread
-
Hello, I thought to start my own Physics Simulation using Newton Dynamics Library. I got most things working; however, Julio Jerez, the creator of Newton Dynamics suggested to make newton update run on its own thread, while the graphics will be performed in SU.
@unknownuser said:For now you do not have a problem, but late when you want to place thousand of objects you will really want that multicourse functionality. It can literally make you code form two to three time faster, and when running asynchronous the physics update is Free!!
Newton already has that multi-core functionality feature, but I'm not sure about SketchUp.
Can anyone please suggest the best solution for multi-threading, or link me a plugin/code snippet that does that.Sincere Thanks
-
Ruby 1.8 has green threads - which is basically Ruby faking threads. So no matter how many threads you create in Ruby, it will still block SketchUp.
At the moment the only other option is to build a Ruby C Extension and create your own native threads.
You might want the performance of C Extensions as well for calculations in general. -
I just dug through the topics on here trying to figure out how to do exactly this, making threads run without blocking Sketchup. I ended up figuring out my own solution, and I hope it's helpful to someone. It's a hack, but it seems to do what I need without any performance problems. I am using it to keep sockets alive, which are running in (green) threads.
eps = 100 #Executions per second UI.start_timer(0.0, true) {sleep 1.0/eps}
I will try to explain my theory as to why it works. As discussed the other topics on threading, Sketchup normally freezes Ruby execution when no blocking Ruby functions are running, meaning that my threads will only run if I am also running a Ruby function in the console. Apparently, though, it isn't a problem the other way around, meaning once Sketchup starts executing its functions, making Ruby run can't stop it. Sleeping for a hundredth for a second gives your thread time to execute, but one hundredth of a second is over well in time for the Sketchup UI to reach its next natural tick. And by that time, it isn't being blocked by Ruby, and as such, can continue, execute normal Sketchup code, and then go back to the Ruby sleep.
It even works nicely alongside SketchyPhysics (when running a simulation) without BugSplat or performance problems.
-
Whatever you execute within the timer block will still block SU's execution. So a lengthy calculation will block for it's entire duration.
And doing calculations is one thing - if you try to modify the model like that you'll be sure to conflict with other tools as it interferes with the undo stack.
-
Thomas, you are right. Until now I have been using it for non-heavy calculations, but I just tested with a heavy calculation that occupies Ruby 100% of the time. Running inside a thread alongside my UI timer loop, it didn't freeze Sketchup at all, but made it noticeably laggy. To fix this, I added some time to the UI.start_timer, so that Sketchup does have time to run Ruby-free.
eps = 100 #Executions per second rr = 0.25 #Fraction of time devoted to Ruby UI.start_timer((1.0-rr)/eps, true) {sleep rr/eps}
I know, this will probably break anything in your thread requiring short and accurate timing. The execution will be 'jumpy' if you are really looking at things in the millisecond range. However, the sleep function still sleeps the expected amount of time.
The one thing I have found is that Sketchup crashes if I try to drag the Ruby window. Not sure why, but it isn't a worry for what I am using it for.
-
@thomthom said:
Ruby 1.8 has green threads
Interesting! What about Ruby 2.0.0, does it involve green threads too?
-
@ttfractal44 said:
eps = 100 #Executions per second > rr = 0.25 #Fraction of time devoted to Ruby > UI.start_timer((1.0-rr)/eps, true) {sleep rr/eps}
Wait, does start_timer actually create a new thread?
BTW, I just realized that Ruby has Thread module.
Thread.new { puts 'pre' sleep(10) puts 'post' }
This does not affect SU at all! However, as TT said, calling SU functions from it mgiht affect performance, but I'll use it only for calculations, while transforming objects will be in SU. -
@anton_s said:
Interesting! What about Ruby 2.0.0, does it involve green threads too?
No, it has native threads. It was introduced in Ruby 1.9.
Here's an interesting read on the topic: http://merbist.com/2011/02/22/concurrency-in-ruby-explained/@anton_s said:
@ttfractal44 said:
eps = 100 #Executions per second > > rr = 0.25 #Fraction of time devoted to Ruby > > UI.start_timer((1.0-rr)/eps, true) {sleep rr/eps}
Wait, does start_timer actually create a new thread?
No, UI.timer does not create a new thread.
@anton_s said:
BTW, I just realized that Ruby has Thread module.
Thread.new { puts 'pre' sleep(10) puts 'post' }
This does not affect SU at all! However, as TT said, calling SU functions from it mgiht affect performance, but I'll use it only for calculations, while transforming objects will be in SU.I'd recommend you search the forum for the topic of threads - there's quite a few that's tried to make use of it. But everyone's been a no-go when real application has been attempted. Threading isn't easy.
-
Everything I have tried in attempting to use Thread in SketchUp has failed miserably.
This works for me:
timer = UI.start_timer(1.0,true) { start = Time now loop do break if Time.now-start > 0.8 ... long computation involving many loops ... end } ... call stop_timer(timer) when appropriate, perhaps from within the loop
My computation is copying a file to a WebDialog; the file is output from another process, and can grow over time to be quite large. This code updates the WebDialog once per second, and permits the "Kill" button (in another WebDialog) to work. Each loop reads 1024 bytes from the file and uses WebDialog#execute_script to append it to a textarea (escape \n and " to keep the JavaScript valid); it handles multiple reads at EOF as the file can grow.
Advertisement