Processing seemingly capped at 35% cpu

Ok so the 15% limitation was due to my power management, but once turned off its still restricted to 35%

Hey There!

Trying using thread() and see if yoy can squeeze the CPU.

https://processing.org/reference/thread_.html

there is a boolean in line 2 to enable your printing again,
but when disabled i see a lot more FPS

Thanks for all your answers everyone, I shall take a look into the threat method. I suppose for now I will just assume its a feature.

1 Like

Just thought I’d revisit this question and see if we can find a solution. For some sketches, ie the spacial partitioning sketch, open processing is a better alternative than the native processing app, however I find it odd that in this day and age this seems to be a limitation which has not yet been overcome. I have not yet looked into threading, as honestly i don’t understand it or how to implement it I am still fairly new to programming, however if someone can point me in the right direction I will read the docs and give it a go. However the ideal solution would obviously be to have my apps be able to utilize the totality of the cpu’s resources.

Anyways if anybody knows any way around this please, any info would be greatly appreciated.

1 Like

even more bad news:

it will not get better soon

with: canvas 800*800 and 5000 of your ?items? ( i not read your code… )

MOD test code
ArrayList<Female> females = new ArrayList<Female>();
boolean diagp=false; //true;
int many = 5000;

void setup() {
  size(800,800);
  frameRate(120);
  for (int i = 0; i < many; i++) {
    PVector location = new PVector(height/2, width/2);
    int[] colours = {floor(random(255)), floor(random(255)), floor(random(255))};
    Female newFem = new Female(location, "female", 1, colours, 16, 10, 10, 10, 10, 50);
    for (int x = 0; x < newFem.moves.length; x++) {
      newFem.moves[x] = new PVector(random(-0.5, 0.5), random(-0.5, 0.5));
    }
    females.add(newFem);
  }
  noStroke();
}
void draw() {
  background(255);
  for (int i = 0; i < females.size()-1; i++) {
    females.get(i).move();
    females.get(i).display();
  }
  if ( frameCount%100  == 0 ) println("fps: "+ frameRate );
}

//Breeder entity object

class Ent {
  ////Abstract properties
  int id;
  int age;
  //'male' or 'female'
  String gender;
  //PVectors
  PVector location;
  PVector velocity = new PVector();
  //n pixels per frame
  float speed;

  ////Physical properties
  //0-255
  int[] colour;
  //4, 8, 16
  int size;

  ////Combat properties
  float hp;
  float damage;
  float b_velocity;
  float f_rate;

  ////Hunger
  boolean hungry = false;
  int hunger = 0;
  int hungermax;

  Ent(PVector location_, String gender_, float speed_, int[] colour_, int size_, float hp_, float damage_, float b_velocity_, float f_rate_) {
    id = floor(random(10000000, 99999999));
    location = location_;
    gender = gender_;
    speed = speed_;
    colour = colour_;
    size = size_;
    hp = hp_;
    damage = damage_;
    b_velocity = b_velocity_;
    f_rate = f_rate_;
  }

  Ent() {
  }

  //void move(){    
  //  location.add(velocity.x * speed, velocity.y * speed);
  //} 
  //Draw Ent on step
  void display() {
    fill(colour[0], colour[1], colour[2]);
    //Wall wrap
    if (location.y > height) {
      location.y = 0.00;
      if (diagp) println("more than height");
    }
    if (location.y < 0) {
      location.y = height;
      if (diagp) println("less than height");
    }
    if (location.x > width) {
      location.x = 0.00;
    }
    if (location.x < 0) {
      location.x = width;
    }
    rect(location.x, location.y, size, size, 5.00);
  }
}



class Female extends Ent {

  boolean pregnant = false;
  int gestation = 0;
  int gestperiod;
  PVector[] moves = new PVector[90];

  int food;
  ////Movement
  //increment 
  int stepcount = 0;
  //change direction when stepcount is a modulus of stepchange
  int stepchange;
  //which move is it up to
  int movenumber = 0;

  Female(PVector location_, String gender_, float speed_, int[] colour_, int size_, float hp_, float damage_, float b_velocity_, float f_rate_, int gestperiod_) {
    super(location_, gender_, speed_, colour_, size_, hp_, damage_, b_velocity_, f_rate_);
    gestperiod = gestperiod_;
    stepchange = floor(random(50, 100));
  }

  void move() {
    if (stepcount % stepchange == 0) {
      velocity.set(moves[movenumber]);
      if (diagp) println(moves[movenumber].x);
      if (diagp) println(velocity);
      if (diagp) println(stepchange);
      movenumber++;
      if (movenumber == 90) {
        movenumber = 0;
      }
    }
    location.add(velocity);
    stepcount++;
  }
}

our usual JAVA 8 Processing 3.5.3

and now i try the JAVA11 version ( possible Processing 4.0.0 beta ) @sampottinger

and same ( or even less ) FPS
and i hoped it might be more ?efficient?
( i not understand why the GPU usage value changed / 12% to 36% / )

so:

processing is cooking on one burner?

2 Likes

OK I might be wrong Javascript is not my thing but surely JS runs in a browser :thinking: in which case the browser’s JS interpreter is running the program, not Processing or the JVM. Perhaps it is being capped by the browser to stop it becoming unresponsive.

Hey there!

On my mac, I ran it and it capped out one of my CPUs to get to 32 FPS on the new Java 11 version. I’ll have to give it a go on a windows machine later. It isn’t expected to use more than one core unless you tell it to explicitly but, that said, Java (specifically the Java 11 version) makes it easy to extend out to other cores and, for sake of demonstration, I went ahead and coded that up for you at: https://gist.github.com/sampottinger/85a76161f959ed407d8f2b87508556dd. Note that running this sketch will require using that new version: https://github.com/sampottinger/processing.

Still, the parallelization there didn’t honestly give me a huge boost. After a little profiling, you may notice are spending almost all of your time in fill and rect! The default renderer in Processing is good at some things but it doesn’t seem to be doing a great job here. However, switch to FX2D (see the code above) and you easily hit 100 FPS on my machine (still without necessarily using up all your cores’ capacity). This means that your work isn’t limited by the computation your sketch has to do (parallelizing the computation at that rate helped a little but not a lot) and, instead, the bottleneck seems to be in the drawing pipeline. It’s hard to say exactly where that is without digging but it may be that you are seeing that some renderers are optimized for certain drawing behaviors over others.

19%20AM

As for Java 11 (the potential new alpha) vs Java 8 (current processing), Java 11 made a lot of changes in the bits that deal with drawing and the way it interacts with the OS. Those aren’t necessarily better or worse… the java community just decided to optimize for some behaviors over others.

Let me know if that helps!

3 Likes

Converted draw() to Java’s classic syntax: :coffee:

import java.util.function.Consumer;

static final Consumer<Female> ACTION = new Consumer<Female>() {
  @Override void accept(final Female f) {
    f.move();
    f.wallWrap();
  }
};

void draw() {
  background(-1);
  females.parallelStream().forEach(ACTION);
  for (final Female f : females)  f.display();
  getSurface().setTitle("fps: " + round(frameRate));
}

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 https://www.geeksforgeeks.org/multithreading-in-java/ ,
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
https://processing.org/reference/thread_.html

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


if i look at the documentation
https://processing.org/reference/size_.html
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.