amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > hollywood: Bitmap aus Array für Brush [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

18.01.2011, 19:24 Uhr

[ujb]
Posts: 423
Nutzer
Ich bastle an einem Hollywoodprojekt, bei dem ich u.a. ein Oszilloskop benötige. Im Moment werden die OSzilloskopdaten als einzellinien aus einem Arry gezeichnet, das ist ber recht cpu-aufwändig (500Linien/125ms verbrauchen ca. 20% cpu-Zeit meines 1.5 GHz G4). Ich nehme an, dass es wesentlich effizienter liefe, wenn ich alle 125 ms vorab eine Bitmap berechnen würde und diese dann als Brush plotten würde.
Nur habe ich keine Anhnung, wie das bei Hollywood funktioniert...
Im Moment nutze ich folgendes Konstrukt (noise[] ist mein eigentliches Datensrray).
code:
temp_o=0
 last_temp_o=0
 For k=0 To 498
    last_temp_o=temp_o
    m=k*5
    temp_o=noise[m+2]+noise[m+4]
    temp_o=temp_o/4
    Line (k+12, 180+temp_o,k+12,180+last_temp_o, $00cc80)
    If k<415
    Line (k+511, 180+oszidata[k],k+511,180+oszidata[k+1], $00cc80)
    EndIf
    oszidata[k]=temp_o
  Next



[ - Antworten - Zitieren - Direktlink - ]

23.01.2011, 20:21 Uhr

Tipsi
Posts: 34
Nutzer
@[ujb]:

Hhmm, leider kenn ich mich da auch nicht
aus. Ich habe zwar kurz einen Blick in
die Anleitung geworfen, aber ich bin nicht
wirklich fündig geworden. Folgende Funktionen
könnten Dir vielleicht helfen:

CreateBrush(id, width, height[, color, table])
SelectBrush(id[, mode])
DisplayBrush(id, x, y[, table])

Aber ob das die CPU weniger belastet?

Griessli
Tipsi

[ - Antworten - Zitieren - Direktlink - ]

24.01.2011, 14:31 Uhr

geit
Posts: 332
[Ex-Mitglied]
Ich habe zwar keine Ahnung, wie Hollywood intern arbeitet und wie du die Daten bekommst, aber normalerweise benötigt so ein Display fast keine Rechenzeit, weil man ja nur einen Sample berechnet und zeichnen muß.

Wenn du ausgibst, während die Daten reinkommen, dann würde ich einen RastPort aufmachen, der der Displaygröße entspricht und dieses Horizontal wieder wie ein Array behandeln. Also den ersten Wert in Spalte 0, den Zweiten in Spalte 1 bis x und dann fängst du wieder bei 0 an.

Dann brauchst du nur 2 Blits um den Hintergrund RastPort in das Fenster zu kopieren und das macht die GPU.

Hast du also gerade Spalte 10 beschrieben (neuster Wert), dann blittest du von Spalte 11 (ältester Wert in der Grafik) bis Spalte x-10, links in deine Ausgabe und im zweiten Anlauf Spalte 0 bis Spalte 10 dahinter ins Fenster. Kein Kopieren, kein Verschieben, kein Löschen des Hintergrundes. Durch das Zeichnen im Hintergrund flackert es nicht mal.

Geit


[ Dieser Beitrag wurde von geit am 24.01.2011 um 14:33 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

24.01.2011, 19:44 Uhr

[ujb]
Posts: 423
Nutzer
@geit & Tipsi:

Mit Hollywood kann man nicht direkt auf das System-API zugreifen. Insgesamt komme ich immer mehr zu dem Schluss, dass Hollywood zwar eine komfortable Sprache ist, aber leider auch recht langsam und an vielen Stellen auch recht limitiert¹

Das zeitaufwändigste waren nicht unbedingt die Linien (die machen etwa 7-10% CPU-Zeit aus), sondern alles, vor allem größere Grafikoperationen.

Nach Rausschmeißen von DisplayBrush und Multiplikationen und redundanten Additionen, verbraucht folgende Routine auf meinem G4 noch immer ca. 15% cpu-Power (die Routine wird 8 mal pro Sekunde ausgeführt). Mir kommt das reichlich viel vor...

code:
Function p_oszi()    ;
  If toggle_oszi = True
  SetFillStyle (#FILLCOLOR)
  Box (12,18, 715, 250,#WHITE) ;alles weiß übermalen
  gfxnoise=188- totalnoise/4
  Line (14, gfxnoise, 928, gfxnoise, #GRAY,2) ;Koordinatensystem
  Line (210, 24, 210, 267, #GREEN)
  Line (410, 24, 410, 267, #GREEN)
  Line (610, 24, 610, 267, #GREEN)
  temp_o=180
  m=0

   For k=0 To 498
     last_temp_o=temp_o
     temp_o=noise[m+2]+noise[m+4]+720
     m=m+5
     temp_o=temp_o/4
     myt0=k+18
     myt1=myt0+498
     Line (myt0, temp_o,myt0,last_temp_o, $00cc80)
     If k<208
     Line (myt1, oszidata[k],myt1,oszidata[k+1], $00cc80)
     EndIf
     oszidata[k]=temp_o
     Next
  EndIf
EndFunction



Mit offscreen in einen Brush von 725x256 px zu plotten und diesen dann per DisplayBrush anzuzeigen (also das, was ich mit der Fragestellung vorhatte) kostet ca. 20% cpu-Zeit. Wie gesagt, auf einem G4/1500...

Dennoch ist Hollywood sehr leistungsfähig und komfortabel, aber mit C++ ist es schon eine andere Hausnummer - sowohl vom Aufwand als auch von der Performance. Ärgerlicherweise bin ich aber zu beschränkt für C++ im allgemeinen und ohne VisualStudio (mit dem Projektmanagement, das ich raffe, der eingebauten Hilfe, msdn und den endlosen Resourcen via google) im speziellen.

--
¹ Ich versuche in Echtzeit ein continuous-Audiosample zu generieren und auszugeben. Ich dachte z.B. an einen circular oder Wechselpuffer als Audiopuffer, geht aber nicht. So stottert die Audioausgabe mit zunehmender cpu-Belastung (die aber noch weit unter 100% liegt).



[ Dieser Beitrag wurde von [ujb] am 25.01.2011 um 02:50 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

25.01.2011, 09:11 Uhr

DrNOP
Posts: 4118
Nutzer
Zitat:
Original von [ujb]:
Insgesamt komme ich immer mehr zu dem Schluss, dass Hollywood zwar eine komfortable Sprache ist, aber leider auch recht langsam und an vielen Stellen auch recht limitiert


Naja, es ist ja auch nicht als allgemeine Programmiersprache entworfen, sondern als Multimedia Layer. Außerdem sind Skriptsprachen eh' immer etwas langsam.

Macht es denn einen Unterschied bei deinen Tests, ob du das als Skript oder Compilat laufen läßt?
--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Antworten - Zitieren - Direktlink - ]

25.01.2011, 11:40 Uhr

[ujb]
Posts: 423
Nutzer
Zitat:
Original von DrNOP:

Naja, es ist ja auch nicht als allgemeine Programmiersprache entworfen, sondern als Multimedia Layer. Außerdem sind Skriptsprachen eh' immer etwas langsam.

Macht es denn einen Unterschied bei deinen Tests, ob du das als Skript oder Compilat laufen läßt?


Nein, es macht keinen Unterschied ob kompiliert oder nicht (es ist ja eben eine interpretersprache). Und ich will Hollywood auch nicht "fertig machen" (es ist wirklich gut und sehr empfehlenswert, da man eine Menge damit machen kann). Aber gerade weil es auf Multimedia spezialisiert ist, hätte ich mir z. B. mächtigere Audiomöglichkeiten erhofft und bin überrascht, dass einfache Grafikoperationen ziemlich viel cpu-Power ziehen.
Eine Vorabversion des Programms, um das es hier geht ist unter http://via.i-networx.de/Simephys/about.htm#down zu finden. Wenn man das startet und die cpu-Load betrachtet während das Oszilloskop läuft oder pausiert, ist der Unterschied schon berächtlich.
Oder zum Testen besser geeignet folgendes sehr einfaches simples Programm: http://via.i-networx.de/temp/stim.lha (MorphOS). Das macht nichts weiter als auf einem 800x600 Fenster 5 einfarbige rechteckige Sprites von 390x80 px zu bewegen - zugegebenermaßen alle 10 ms. Aber es fordert meinem G4/1500 ca. 80% cpu-Power ab - und das erscheint mir für diese Aufgabe recht viel.
Aber es ist super, dass es so einfach zu programmieren ist. Und: es läuft ja! Das beste ist, dass es auch Win-Executables erzeugen kann. Z.B war mir dieses kleine stim-Programm im Job bereits recht nützlich (und zahlreiche andere solcer Miniprogramme). Ein CoreDuo hat damit auch weniger Probleme. Aber es ist dann eben doch eher die brute force-Methode.


[ - Antworten - Zitieren - Direktlink - ]

25.01.2011, 12:51 Uhr

geit
Posts: 332
[Ex-Mitglied]
@[ujb]:

Was Rechenzeit frisst kannst du ja einfach durch weglassen ausprobieren.

Fakt ist, das die Methode, die ich beschrieben habe nur einen "Line" und zwei Blits braucht.

Wenn Hollywood also Grafik auch in einen nicht sichtbaren bereich schreiben kann und diesen Bereich als Block kopieren kann, dann sollte das deutlich schneller gehen, als jedesmal den kompletten Bildschirm neu zu zeichen, was vom Prinzip schon unsinn ist , wenn 99% der Daten die man zeichnet sich nicht ändern.

Wenn sich nur ein Wert ändert, braucht man auch nur einen zu zeichnen. Wenn du natürlich 480 neue Werte auf einen Schlag bekommst, ist deine Variante die sinnvolle.

Geit

[ - Antworten - Zitieren - Direktlink - ]

25.01.2011, 13:23 Uhr

[ujb]
Posts: 423
Nutzer
@geit:

Ich plotte alle 125 ms nun 708 Werte, davon 499 neu berechnete Werte. Das ganze entspricht einem nicht kontinuierlichen Digitaloszilloskop bei 4 kHz Samplingfrequenz. 209 Werte könnten eigentlich von der vorigen Iteration übernommen werden, aber es kostet mehr cpu-Zeit den vorigen Brush zu kopieren als 209 neue Werte zu zeichnen.

[ - Antworten - Zitieren - Direktlink - ]

25.01.2011, 14:09 Uhr

DrNOP
Posts: 4118
Nutzer
Zitat:
Original von [ujb]:
Nein, es macht keinen Unterschied ob kompiliert oder nicht (es ist ja eben eine interpretersprache).

Das war ja der Hintergrund meiner Frage: Wenn aus dem Hollywood-Compiler genauso Binärcode herausfallen würde wie aus z.B. einem C-Compiler, müßte es nicht mehr interpretiert werden und könnte dadurch vielleicht schneller laufen.
--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Antworten - Zitieren - Direktlink - ]

31.01.2011, 17:04 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von DrNOP:
Das war ja der Hintergrund meiner Frage: Wenn aus dem Hollywood-Compiler genauso Binärcode herausfallen würde wie aus z.B. einem C-Compiler, müßte es nicht mehr interpretiert werden und könnte dadurch vielleicht schneller laufen.

Das, was dann potentiell schneller ausgeführt wird, ist der Teil des Codes, der sich unterscheidet, in diesem Fall also die relativ triviale Schleife, die die Grafikbefehle als Unterprogramme aufruft. Der Code dieser Unterprogramme ist dagegen immer derselbe, egal ob der Aufrufer ein Interpreter oder kompilierter Code ist. Und wenn die meiste Zeit innerhalb der Grafikroutinen verbraten wird, ergibt sich zwischen interpretiert und kompiliert auch kaum ein Unterschied.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

01.02.2011, 20:13 Uhr

Evil
Posts: 156
Nutzer
Hallo UJB:
Versuche doch mal, den code etwas zu optimieren!
Ich habe zum Beispiel die Erfahrung gemacht, daß man besser (und schneller) eine kompliziertere Formel berechnen lassen kann, als mehrere kleine. (hier myt0, myt1, temp_0 und m)
Außerdem ist es schneller, wenn man bei If-Verzweigungen besser alles in eine Zeile schreibt (wenn nur ein THEN-Befehl folgt), anstatt mehrere Zeien zu nutzen.

Das sollte schon das ein oder andere Prozent bringen

Function p_oszi()
If toggle_oszi = True
SetFillStyle (#FILLCOLOR)
Box (12,18, 715, 250,#WHITE)
gfxnoise=188- totalnoise/4
Line (14, gfxnoise, 928, gfxnoise, #GRAY,2)
Line (210, 24, 210, 267, #GREEN)
Line (410, 24, 410, 267, #GREEN)
Line (610, 24, 610, 267, #GREEN)
temp_o=180

For k=0 To 498
last_temp_o=temp_o
temp_o=(noise[m+2]+noise[m+4]+720)/4
Line (k+18, temp_o,k+18,last_temp_o, $00cc80)
If k<208 THEN Line (k+516, oszidata[k],k+516,oszidata[k+1], $00cc80)
oszidata[k]=temp_o
Next
EndIf
EndFunction

In diesem code befinden sich innerhalb der Schleife anstatt 12 nur noch 5 Zeilen Code.

Desweiteren müßte man doch eigentlich die Variable last_temo_o durch oszidata[k-1] ersetzen können.
Dadurch würde man noch eine Zeile Code wegnehmen können (last_temo_o=temp_o).
Allerdings müßte man dazu mehr über das programm wissen, um das genau sagen zu können.

Ich hoffe, ich konnte dir ein wenig helfen!!!

Grüße

Jörg

[ - Antworten - Zitieren - Direktlink - ]

02.02.2011, 17:38 Uhr

[ujb]
Posts: 423
Nutzer
@Evil:

Ja, das gab gut 3% weniger cpu-Belastung, also nur noch 10% load. Das oszidata[] arry benötige ich an anderer Stelle noch.
Die verkürtze if-Syntax hatte ich nicht bedacht, ebenso war in in der Annahme, dass es güsntiger wäre einer lokalen Variable einen Wert zuzuweisen und auf diesen mehrfachzuzugreifen, als mehrfach direkt einen Wert aus einem Array zu fischen.
Die 2. Zeile der Schleife musste ich noch umbauen und ich bin überrascht, dass
temp_o=(noise[k*5+2]+noise[k*5+4]+720)/4
fixer geht als
m=m+5
temp_o=(noise[m+2]+noise[m+4]+720)/4

Zwei Multiplikationen schneller als 3 additionen. Hätte ich nicht gedacht, ich hätte Multiplikationen teuerer eingeschätzt.

Super Tipps!

[ - Antworten - Zitieren - Direktlink - ]

02.02.2011, 20:14 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Zwei Multiplikationen schneller als 3 additionen. Hätte ich nicht gedacht, ich hätte Multiplikationen teuerer eingeschätzt.
Willkommen in der Gegenwart. :D

Aber wenn Microoptimierungen hier so viel ausmachen, dann schau mal, ob
Du die Division weg bekommst. Die ist nämlich nach wie vor die teuersten Operation der Grundrechenarten. Wenn Hollywood einen Right-Shift-Operator anbietet, dann los.

Ansonsten poste ruhig mal den resultierenden/aktuellen Stand. Solche Optimierungen zu finden, ist ja nicht zu schwer. Nur die Grafikoperationen selber, da kann man nicht viel machen.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

02.02.2011, 23:26 Uhr

[ujb]
Posts: 423
Nutzer
@Holger:
Der Unterschied zwischen drei Additionen und zwei Divisionen ist absolut gesehen etwa 0,5% Prozessorlast. Die Routine läuft etwa 1.3 mal so schnell ab und benötigt im einen Fall ca. 2.5% und im anderen Fall ca. 1.95% der cpu-Zeit. Sind aber nur grobe Schätzungen aus dem Taskmanager. Was ich bei 3992 Wiederholungen/s bei einem G4/1500 reichlich viel finde. Sieht mir doch sehr danach aus, als sei nicht unbedingt die Operation selbst cpu-aufwändig, sondern der Aufruf.


[ - Antworten - Zitieren - Direktlink - ]

03.02.2011, 11:10 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von [ujb]:
@Holger:
Der Unterschied zwischen drei Additionen und zwei Divisionen ist absolut gesehen etwa 0,5% Prozessorlast.

Ich glaube kaum, dass Du die Divisionen durch Additionen ersetzen kannst. Möglicherweise verwechselst Du da gerade etwas.

Dass Multiplikationen gegenüber Additionen kaum noch einen Unterschied machen, ist dagegen heute normal, vor allem, wenn man bedenkt, dass in Deiner ersten Fassung zwei der Additionen auf das Ergebnis der ersten warten mussten (nicht parallelisierbar), das noch in einer Variablen zwischengespeichert wurde (zusätzlicher Overhead).
Die zwei Multiplikationen sind dagegen nicht voneinander abhängig und können parallel ausgeführt werden.

Das heißt, bei angenommenen 2 Taktzyklen für eine Multiplikation und 1 Zyklus für eine Addition ist die Variante mit drei Additionen und einer Variablenspeicherung schon langsamer. Hinzu kommt natürlich noch jeder fixe Overhead pro Operation, den Hollywood möglicherweise hinzufügt.

Aber was ist, wenn Du beispielsweise
code:
m=m+5
temp_o=(noise[m+2]+noise[m+4]+720)/4


durch
code:
temp_o=(noise[m+7]+noise[m+9]+720)/4
m=m+5

ersetzt?

Wie dem auch sei, ich kann mir nicht vorstellen, dass der Overhead von Hollywood pro Operation in der Größenordnung einer Division liegt. Diese zu entfernen sollte einen spürbaren Effekt haben. Falls man sie denn entfernen kann. Wenn Hollywood keine Right-Shift Operator anbietet, müsste man das durch einen angepassten Algorithmus ändern.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > hollywood: Bitmap aus Array für Brush [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.