Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Laufzeitverschlechterung durch Auslagerung in einzelne Threads
ich habe mich irgendwie festgebissen: ich wollte ein Programm verschnellern, mit dem ich schon recht fix Bildpunkte (eines BufferedImage) durch jeweils zwischen 1000 und 10.000 Iterationen berechne. Meine ursprüngliche Variante sah im Wesentlichen so aus:
Java:
for(int i=0;i<Bildbreite;++i){
for(int j=0;j<Bildhoehe;++j){
iteriere(i,j);
}
}
public Color iteriere(int i, int j){
Color erg;
for(int k=0;k<Iterationen;++k){
//Iterationsschritt
if(Abbruchbedingung){
//berechne erg
break;
}
}
return erg;
}
Nun hatte ich einfach ganz naiv die Iterationen
für jeden Punkt in einen Thread gepackt:
Java:
public class Iteration extends Thread{
int i;
int j;
public Iteration(int i, int j){
this.i=i;
this.j=j;
start();
}
public void run(){
for(int k=0;k<Iterationen;++k){
//Iterationsschritt
if(Abbruchbedingung){
//Farbe setzen
break;
}
}
}
}
und dann gestartet:
Java:
for(int i=0;i<Bildbreite;++i){
for(int j=0;j<Bildhoehe;++j){
new Iteration(i,j);
}
}
Leider mit dem Ergebnis, dass das Programm nun 12 mal so lange brauchte. Ich muss da irgendwo einen dicken Denkfehler haben.
Du legst Bildbreite * Bildhoehe Threads an. Das ist entschieden zu viel. Es sollten nicht mehr Threads gestartet werden als Prozessoren bzw. Kerne vorhanden sind. Darüber hinaus wird es nicht schneller, durch das aufwendigere Scheduling sogar langsamer.
Hab ich schon befürchtet In diesem Fall aber noch eine Nachfrage: wenn ich 20 Instanzen meines ursprünglichen Progamms öffne, habe ich ungefähr das Maximum dessen erreicht, was ich öffnen kann, ohne dass sich die Bildberechnung in der einzelnen Instanz verlangsamt. Für eine Bilderserie hatte ich jetzt im Kopf, per Batch-File immer 20 Instanzen gleichzeitig zu starten, indem eine fertiggewordene Instanz per System.out.println("fertigNrXXX") anzeigt, dass sie durchgelaufen ist. Da ich mich mit Batch-Files nur sehr beschränkt auskenne und das irgendwie nicht besonders elegant wirkt: siehst Du eine andere Alternative?
Für eine Bilderserie hatte ich jetzt im Kopf, per Batch-File immer 20 Instanzen gleichzeitig zu starten, indem eine fertiggewordene Instanz per System.out.println("fertigNrXXX") anzeigt, dass sie durchgelaufen ist.
Das würde ich nicht tun, im Vergleich zu simpler Rechnerei ist Konsolenausgabe eine sehr teure Operation (lass Deinen Rechner 1000 mal irgendwas berechnen und dann vergleiche mit der gleichen Rechnerei aber Ausgabe jedes Ergebnisses, der Unterschied ist markant).
Besser: ein Thread wacht über die Bilder und mehrere andere Threads bearbeiten diese. Immer wenn ein Thread mit seiner Bearbeitung fertig ist, holt er sich beim ersten Thread wieder neue Daten, bis dieser nichts mehr zu Bearbeiten hat.
Wichtig ist natürlich auch, dass sich die Threads nicht gegenseitig behindern dürfen ([c]synchronized[/c] ist damit gewisserweise verboten). Für die Berechnung eines Fraktals bin ich ähnlich vorgegangen wie FatFire, allerdings habe ich den arbeitenden Threads (4 Stück, ergo 2 pro Kern, ich glaube, man kann diese Kernzahl irgendwo abfragen) ihre Bereiche vorher fest zugewiesen; lässt sich ja auch simpel berechnen.