Reputation: 57
I'm working on a processing sketch here: https://github.com/davidcool/processing/tree/master/polyhedrons/polyhedrons_4
It's not very elegant code-wise but works fine. It renders rotating complex (meaning many faces) polyhedrons to the screen. Each time you click it adds 5 new rotating polyhedron objects... Once you have 20-25 objects it starts to bog down, meaning the frames/sec drop and it looks jumpy.
I've been reading about threading in Processing/Java. So I started to think maybe I could split the total number of objects out to each processing core. I saw this example in particular: http://www.camnewnham.com/threading-in-processing/
Before I dive into this goose chase, does anyone know if threading would help in terms of animation speed? When I run a sketch normally does it always just use one core for the draw loop? Can threading spread out the object animation rendering over "idle" cores?
Thanks!
Upvotes: 4
Views: 952
Reputation: 42176
The draw() function is always called by the same Thread. This same Thread also calls the mousePressed() and similar functions. In Processing this is called the Animation Thread- Java has a similar idea, called the EDT.
So you can't simply move your drawing to other threads. This will cause problems with the rendering- for example, the Animation Thread might be trying to draw the next frame, while your drawing threads are still trying to draw the previous frame. It's not going to work.
You could try to do your own multi-threaded off-screen buffering by having all your helper threads draw to a PGraphics instead of calling the Processing drawing methods directly. You'd then have to synchronize all of your drawing threads and only draw your PGraphics to the screen (using the Animation Thread) after all of those threads have finished.
This is not a particularly difficult job, but it does involve a pretty decent understanding of how threading works, which goes beyond the scope of most Processing sketches.
Also note that JavaScript doesn't have multiple threads, so anything you do with threading will not work in JavaScript mode.
Here's an example sketch that uses just the Animation Thread to draw 10000 random points every frame. I get about 7 FPS with it:
PGraphics sharedGraphics;
void setup(){
size(500, 500);
sharedGraphics = createGraphics(500, 500);
}
void draw(){
sharedGraphics.beginDraw();
sharedGraphics.background(0);
for(int i = 0; i < 10000; i++){
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
sharedGraphics.endDraw();
image(sharedGraphics, 0, 0);
println(frameRate);
}
And here is how you might use multiple Threads to render to a PGraphics:
PGraphics sharedGraphics;
void setup() {
size(500, 500);
sharedGraphics = createGraphics(500, 500);
}
void draw() {
ArrayList<Thread> threads = new ArrayList<Thread>();
sharedGraphics.beginDraw();
sharedGraphics.background(0);
for (int i = 0; i < 100; i++) {
Thread t = new DrawThread();
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
t.join();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
sharedGraphics.endDraw();
image(sharedGraphics, 0, 0);
println(frameRate);
}
class DrawThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
}
}
However, the performance of that is even worse than the single-threaded model, and I get strange artifacts (some of the ellipses are filled, others are not) which suggests that PGraphics is not thread-safe. That might depend on the type of renderer you're using. You might then add some synchronization:
class DrawThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
synchronized(sharedGraphics) {
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
}
}
}
That works, but the performance of it is even worse, since you're still only accessing the PGraphics with one thread at a time, and you're doing a bunch of extra work every time draw() is called.
You might be able to fiddle around with it to make it work, but the end result is that it's probably not worth it.
"Some people, when confronted with a problem, think “I know, I'll use multithreading”. Nothhw tpe yawrve o oblems."
Upvotes: 3