Processing seemingly capped at 35% cpu

for the OP question

-a- using one CPU “logical processor” only Processing not uses your computer power
unless using expert JAVA multithreading as sampottinger and GoToLoop show.
also Multithreading in Java - GeeksforGeeks ,
and the old JAVA 8 and new JAVA 11 is obviously different.

in default Processing 3.5.3 see
File / Examples / Topics / Advanced Data / Threads
and

-b- using other RENDERER would be the best answer for this question
see


if i look at the documentation

where several renderer are mentioned,
special to choose between the 3 ( not 3D )
default-JAVA2D / FX2D / P2D
should somewhere be more info, like which can not draw what element…
or is not available on what hardware or operating system.
is there a good info / tutorial link?


-c- as a overview of RENDERER / Processsing version / Threading
my test data / depending on
hardware / operating system / sketch code / sketch settings like canvas size 800*800

void setup() {
//  RENDERER          |       P353       |      P400b      |  P400b THREAD   |
//  testing           |    FPS CPU% GPU% |   FPS CPU% GPU% |   FPS CPU% GPU% |
//  size(800,800     );//   39  11   37  |    37  11   35  |    39  11   35  |   // JAVA2D 
//  size(800,800,FX2D);//  190  17   31  |   195  16   12  |   200  17   11  |
//  size(800,800,P2D );//   6.5 11   17  |    5.9 10   15  |    5.8 10   15  |
//  size(800,800,P3D );//   6.4 11   17  |    5.7 10   16  |    5.8 10   16  |
  frameRate(200);  // change target range

sorry GoToLoop version

parallelStream()

not tested for data here.


@sampottinger
looking at the data i rechecked and now think that
JAVA11 FX2D is able of a internal threading
for this i play with the target frameRate 200 → 250 what works
and shows a clear 2 cpu usage,
over 300 i get a frameRate of 30 ???

I wouldn’t want to maximize cpu usage, but to maximize framerate and performance, while keeping cpu usage as low as possible. More cpu usage means more power consumption. It is easy to use all the cpu if that’s the goal (this is more like a joke): start 8 threads doing non stop calculations :slight_smile: But it would achieve nothing useful.

My question then would be how to achieve what you are trying to do with 5% cpu usage :slight_smile:

But to give more details, a program can have different bottlenecks that makes it not perform well: disk access, memory usage and the type of data structures used, cpu usage and the amount of data that is transferred on each frame to the gpu. So to get a smoother animation a program should try to limit these: less disk access (ideally in a spearate thread), less memory and cpu usage, and sending less data to the gpu. Sometimes more ram usage can lead to less cpu usage though, it depends on the details.

The example you shared which draws lots of hexagons would use almost no cpu at all if the hexagons were kept in a texture in the gpu (therefore avoiding to send all those hexagons on every frame to the gpu). Then you would need to update part of the texture only when/if it changes. To detect which hexagon is hovered by the mouse is not necessary to ask each single hexagon “are you under the mouse?”, but you can figure that out with a simple calculation to convert mouseX and mouseY into the index of the grid item. What I’m trying to say is that the problem is not that cpu can’t be maxed, but that the algorithm is not very efficient :slight_smile:

update: on the other hand, it can also be an issue with the computer overheating, but that would affect all programs, not just Processing: cooling device not properly attached to the cpu, fan not working or too dusty, etc.

4 Likes

Here an alternative version of your first program:

int cols, rows;
int scl = 20;
int w = 2000;
int h = 1600;

PShape[] stripe;

void setup() {
  size(600, 600, P3D);
  frameRate(450);
  cols = w / scl;
  rows = h/ scl;
  stripe = new PShape[rows];
  for(int i=0; i<rows; i++) {
    stripe[i] = createShape();
    stripe[i].beginShape(TRIANGLE_STRIP);
    for (int x = 0; x < cols; x++) {   
      stripe[i].vertex(x*scl, 0, 0);
      stripe[i].vertex(x*scl, scl, 0);
    }
    stripe[i].endShape();
  }
}

void draw() {
  int N = frameCount % rows;
  int count = stripe[N].getVertexCount();
  for(int i=0; i<count; i+=2) {
    int x = (i/2) * scl;
    stripe[N].setVertex(i, x, 0, 200 * noise(x * 0.02, frameCount * 0.3) - 100);
    stripe[N].setVertex(i+1, x, scl, 200 * noise(x * 0.02, (frameCount+1) * 0.3) - 100);
  }

  background(0);
  stroke(255);
  fill(120);
  translate(width/2, height/2+50);
  rotateX(1.1);
  translate(-w/2, -h/2);
  for (int y = N+1; y < N+1+rows; y++) {
    translate(0, scl);
    shape(stripe[y%rows]);
  }
  if (frameCount % 100 == 0) println(frameRate);
}

My rewrite is super messy, sorry, I was doing it without any planning :slight_smile: But I just wanted to show that it’s possible to get better results by optimizing the program. I did two things: send less data to the graphics card on each frame (less calls to vertex()), and do less noise() calculations. The way I did it is: I keep an array of PShapes with strips. Those strips are slices of the landscape. Those slices don’t need to be recalculated on every frame, because the landscape doesn’t morph, it only moves. Those slices (PShape) are kept in the GPU by default. So the only thing that needs to be recalculated and sent to the GPU is one new slice on each frame.

With this approach I could go from 90 fps to more than 450.

I could also lower scl to small numbers like 5 and it worked fine too.

It’s often a trade off between simple code that is easy to understand for the programmer and code that performs better but is harder to reason about.

3 Likes

Excuse me, remind me what’s this again? How can I program on an iPhone or iPad?

1 Like

I think “native app” just means running out of a desktop PDE here – as opposed to any of the browser-based options like p5.js openprocessing etc.

2 Likes

Thank you! It would be great to program on an iPad native

There is no PDE on iOS, but recently Processing for iOS was open sourced, and it has a github repo. It is also available on the iOS app store as Processing iCompiler.

Its core is built on processing.js, though – not Processing 3 or p5.js.

Past discussion of older Processing iOS options – https://forum.processing.org/two/discussion/comment/81152/#Comment_81152

There is also an iOS app called CodeNaturally, which I haven’t tried but I believe is p5.js-based and might be an interface to a web editor.

2 Likes

Of course the goal here is not to have my cpu be maxed out, the goal here is to have my sketch make use of as much cpu available and necessary, which it just wasn’t doing. I’ll be more careful with my wording in the future.

1 Like

I meant the native desktop windows app.

1 Like

Not in this case, some sketches in open processing (online portal) run better than on the desktop version. P5.js however is a subset of processing made to run explicitly through a javascript file. This will run a lot slower than the native processing code.

For now it seems that changing the renderer is by far the simplest and quickest method, not sure if there are any drawbacks to this method which have yet to be identified. Still I think I’ve understood more about how processing works and the limitations of this software. Currently and correct me if I’m wrong the application makes use of only one thread, workarounds are available to extend to other cpu’s however this does not offer a great performance boost and requires the use of processing 4 beta, and java 11.

Just struggling at the moment to get these last two running on my desktop so I will update you once I have. But so far extremely happy with the outcome of the discussion, as I now have access to far higher framerates for my sketches.

Thank you to everyone for your contributions.

sorry my test give you that impression, but
it is just that i read GoToLoop 's post too late
and not tested P353 threading ( with your code )
but we give you info where to start.


while i see that as a good stress-test for P353 / P400b
and not even read your code,
possibly i should not have brought that P400b thing into your thread,
but i hoped on a boost so i published the results anyway.

and hamiod wanted to tell you that primary the code should be optimized,
not so much the threading…


but yes start first with:
-+ no println from draw
-+ test noSmooth() / Reference / Processing.org
-+ no full / big screen settings
-+ less ‘items’ can also make a great show

++ check for 2D the 3 renderer options
++ create shapes in setup, not in draw
++ GPU optimization of your code ( link to tutorial ? )
++ check your app design if threading is possible and gives a boost

++ also must say that stress testing processing can be interesting,
but for the quality of art not really need 120FPS for > 62000 items…

also if you want produce a result ( picture or video ) you can optimize regarding your hardware…
but in case you intend to share your code ( and then it not performs on our budget PC’s )
nobody would be happy…


anyhow thanks for your input and your patience
hope the off-point topics have been interesting and not too much distracting…

1 Like

Really glad that it is working well for you!

Yes, Processing’s render / draw loop is one thread.

as @kll mentioned, thread() is built-in, it isn’t a workaround, and Thread is also a Java built-in that you can use in Processing 3 – no beta 7 / Java 11 required.

The performance boost really depends on tiny details of what you are doing – it can be really dramatic, or it can be worse than not using threads at all.

You can use basic threads pretty easily, HOWEVER, all kinds of Processing drawing internals are not thread-safe. So if you want threads, in general you cannot draw in threads, or compute colors in threads (without actual workarounds). Instead you should do intensive calculations or data processing in the threads, pass the results to the main draw thread, and draw in that one thread based on those results. See for example this past discussion:

@hamoid’s advice is solid – optimizing code is usually the best place to start. Also, if you really need performance, learning gpu shaders can be arcane (like threading) but usually provides concrete performance boosts – threads can sometimes help, but shaders almost always help.

2 Likes

Direct comment link for my “Linked Balls” multi-thread double PGraphics sketch: :thread:

2 Likes

Nearly 60fps with 36000 (6000*6) entities, 6 entity display threads and PImage rect caching:

3 Likes

A few questions about your code.

  background(isMainCanvas? altCanvas : mainCanvas);

What does this mean?

Also is this running two canvases, I don’t completely follow how you’re using the render function in thread.

if (isLooping ^= true)

also what does the ^= mean?

Thanks.

Thanks, this is really great take on the original. I completely understand that it makes sense to calculate all vertices before entering draw, then the program, doesn’t have to do calculations and drawing whilst running.

Ok so, I’ve figured out how to get processing 4 working. The only thing I don’t understand is how your initializing the multithreading.

 females.stream().parallel().forEach((female) -> {
    female.move();
    female.wallWrap();
  });

Is it this bit of code doing the entire work?

Hey there @paulgoux! Yep that’s all you need to do multithreaded processing. So streams go through each element of a collection. In this case I am telling Processing to:

  • females.stream(): Start streaming (going through) the elements of the females collection.
  • .parallel(): Split this stream up so that its contents can be run through in parallel. Without this, it will do it serially (one by one) by default.
  • forEach(: For each element in the stream, perform the following operation.
  • (female) ->: Call the element I am currently on female.
  • { ... }: Perform this operation for each female in females. In this case I am calling move and wallWrap on each.

You can think of (female) -> { ... } as a defining a method / function without a name that takes in a single parameter called female.

For more info about streams see https://www.baeldung.com/java-8-streams-introduction. I love streams and they can (maybe not in this case but often) help make your code move quite a bit faster. If you have questions about how to do something using this functionality, feel free to at mention me. :smiley:

3 Likes

Oh! If you haven’t seen this .method1().method2() type syntax before… It’s called method chaining. Here’s an explanation: https://www.javamex.com/java_language/method_chaining.shtml

3 Likes