Zeige Ergebnis 1 bis 5 von 5
  1. #1
    Benutzerbild von Amorphis
    Registriert seit
    Jan 2012
    Beiträge
    212
    Likes
    0

    Auslöser optimieren

    Guten Morgen

    ich habe unter meinen Auslösern 22 welche auf "Eine Einheit stirbt" reagieren und davon brauche ich auch noch ein paar mehr für Statistiken die ich erstellen möchte.

    Aktuell funktioniert noch alles gut, aber ich denke mir das es sicher irgendwann zuviele sind. Daher wollte ich mehrere Auslöser mit einander verketten. Also Auslöser 1 reagiert auf das Ereignis und startet nacheinander die anderen Auslöser.

    Jetzt meine Frage, es gibt ja, neben normalen Auslösern, noch Aktionen und Funktionen. Würde mir das eine Performance Steigerung bringen wenn ich das Nutze anstelle von den verketteten Auslösern?

    Letztendlich würde ich ja, wenn ich Funktionen nutze, diese auch nur dann aufrufen wenn ich sie benötige. Also im Prinzip das gleiche, oder vielleicht doch nicht ?


  2. #2
    Maps Benutzerbild von Ahli
    Registriert seit
    Mai 2006
    Ort
    in Seenähe
    Beiträge
    826
    Likes
    0
    Jedes Event started einen Auslöser, wenn dieser feuert (egal wie die Bedingungen gesetzt sind).
    Daher ist der optimale Weg, einen Auslöser zu haben, in dem alles überprüft wird. Der Performancegewinn ist allerdings sehr, sehr gering.

    ABER es gibt ein Thread-Limit von 1024. Jeder Auslöser und jede Aktion mit aktivierter Thread-Option benutzen einen der Plätze pro Instanz (d.h. wenn der Code durchläuft. Wenn man Aktionen benutzt, die "warten", dann bleibt der Threadplatz über längere Zeit hinweg belegt bis der Code komplett durchgelaufen wird).
    Sterben bei dir 100 Zerglinge im selben Moment (z.B. durch eine Atomrakete) und jede tote Einheit löst bei dir 11 Auslöser aus, dann wird dein Code nicht alle Todesfälle ordentlich registrieren, da diese dann 100*11=1100 Plätze beanspruchen würden. Daher ist es bei manchen Events sehr sinnvoll, diese in einem Auslöser anstatt Mehreren zusammenzufassen.

    Einen Auslöser per Aktion zu starten, benutzt auch einen weiteren Thread (zumindest, wenn nicht gewartet wird... bei der Warte-Option könnte es sein, dass der ander Auslöser im gleichen Thread läuft).

    Falls jemand nun denkt, Threads wären super, wenn man mehrere CPU-Kerne hat, dann liegt man bei SC2 leider falsch. Diese Threads sind nur Jobs, die in sequenzieller Reihenfolge abgearbeitet werden. Deshalb ist die Reihenfolge von Auslösern zu 100% vorhersehbar. Bei richtigen Threads, ist die Reihenfolge nicht (wirklich) festgelegt.

    --

    Generell sehe ich es als besseren Stil an, Aktionen anstatt Auslöser zu benutzen, da dies dem richtigen Programmieren ähnlicher ist und man durch die Parameter Informationen übertragen kann, welches bei Auslösern nicht möglich ist.
    Geändert von Ahli (02. Mai 2014 um 05:26 Uhr)
    meine Diablo1 map
    Ahli: hab nie wc3 gemappt :S bin glatt von scbw zu sc2
    Tomura: oh
    muzzel: OH


    Werbung hält Fanpages am Leben. Bitte deaktiviert Adblock auf den Seiten, die ihr unterstützen wollt.

  3. #3
    Benutzerbild von Amorphis
    Registriert seit
    Jan 2012
    Beiträge
    212
    Likes
    0
    Zitat Zitat von Ahli Beitrag anzeigen
    Jedes Event started einen Auslöser, wenn dieser feuert (egal wie die Bedingungen gesetzt sind).
    Daher ist der optimale Weg, einen Auslöser zu haben, in dem alles überprüft wird. Der Performancegewinn ist allerdings sehr, sehr gering.
    --
    Daher ist es bei manchen Events sehr sinnvoll, diese in einem Auslöser anstatt Mehreren zusammenzufassen.
    Ja das ist mir soweit klar. Mein Problem ist noch das ich nur wenige der Auslöser zusammenfassen könnte, weil ich bei den meißten die Auslösende oder Vernichtende Einheit bzw Spieler abfrage.

    Wenn ich nach dem auslösen des Auslösers die Einheit oder den Spieler in einer Variable speichere um die Werte in anderen Auslösern abzufragen kann es sein das die Werte schon wieder überschrieben worden bevor alle Auslöser einmal durch gelaufen sind.

    Würde ich die besagten Auslöser zusammenfassen oder auch nur ein Teil, anstatt sie nacheinander verkettet ablaufen zu lassen, kommt noch das Problem dazu das hier und da unterschiedliche Bedingungen überprüft werden. Dann hätte ich dadurch einige IF-Anweisungen im Auslöser und der Auslöser wäre insgesamt auch wieder recht lang, sodass der eventuell wieder neugestartet wird bevor er einmal durchgelaufen ist.


    Auf der Karte sterben regelmäßig Einheiten, vorallen wenn Spieler gegeneinander kämpfen. Zwar keine riesigen Mengen, aber oft schnell nach einander.

    Aber die Info mit den 1024 maximalen Threads ist gut zu wissen, danke
    Ich versuche einfach dadrunter zu bleiben und so viele Auslöser zusammenzufassen wie es geht.


    Aber eine Frage habe ich noch:

    Sagen wir mal ich habe jetzt 2 Auslöser die auf "Eine Einheit stirbt" reagieren.
    Dann stirbt eine Einheit und beide lösen aus.
    Jetzt belegen die Thread 1 und Thread 2.
    Bevor die beiden Auslöser durch gelaufen sind und die Threads frei werden,
    stirbt jetzt noch Eineinheit.
    Die beiden Auslöser lösen wieder aus.

    Belegen die dann Thread 3 und Thread 4, und werden abgearbeitet sobald 1 und 2 durch gelaufen sind ?
    Oder werden dann Thread 1 und Thread 2 überschrieben?


    Wenn ersteres der Fall ist und man genug freie Threads hat bzw. nicht zu viele Auslöser nutzt, hätte man ja immer noch ein Puffer und die Auslöser könnten doch etwas länger werden.

    Konnte man dies bezüglich nicht sogar was im Editor einstellen ?
    Geändert von Amorphis (02. Mai 2014 um 12:20 Uhr)

  4. #4
    Maps Benutzerbild von Ahli
    Registriert seit
    Mai 2006
    Ort
    in Seenähe
    Beiträge
    826
    Likes
    0
    Zitat Zitat von Amorphis Beitrag anzeigen
    Würde ich die besagten Auslöser zusammenfassen oder auch nur ein Teil, anstatt sie nacheinander verkettet ablaufen zu lassen, kommt noch das Problem dazu das hier und da unterschiedliche Bedingungen überprüft werden. Dann hätte ich dadurch einige IF-Anweisungen im Auslöser und der Auslöser wäre insgesamt auch wieder recht lang, sodass der eventuell wieder neugestartet wird bevor er einmal durchgelaufen ist.
    Auslöser werden nicht neu gestartet bevor der Code durchgelaufen wird. Auslöser laufen so lange, bis man im Code wartet (oder SC2 sie beendet, da sie zu lange laufen). Auslöser starten grundsätzlich in einer eigenen Instanz, d.h. lokale Variablen werden nicht überschrieben.

    Zitat Zitat von Amorphis Beitrag anzeigen
    Auf der Karte sterben regelmäßig Einheiten, vorallen wenn Spieler gegeneinander kämpfen. Zwar keine riesigen Mengen, aber oft schnell nach einander.
    Im Normalfall lässt man Threads nur so lange leben wie notwendig. Daher solltest du wohl keine Warte-Aktionen in deinem Code haben. Daher ist nur die Menge der Einheiten interessant, die exakt zum selben Zeitpunkt sterben.

    Zitat Zitat von Amorphis Beitrag anzeigen
    Sagen wir mal ich habe jetzt 2 Auslöser die auf "Eine Einheit stirbt" reagieren.
    Dann stirbt eine Einheit und beide lösen aus.
    Jetzt belegen die Thread 1 und Thread 2.
    Bevor die beiden Auslöser durch gelaufen sind und die Threads frei werden,
    stirbt jetzt noch Eineinheit.
    Die beiden Auslöser lösen wieder aus.

    Belegen die dann Thread 3 und Thread 4, und werden abgearbeitet sobald 1 und 2 durch gelaufen sind ?
    Oder werden dann Thread 1 und Thread 2 überschrieben?
    Threads sind in einer Warteschlange, die abgearbeitet wird, von daher haben sie keine festen Slots. Die Reihenfolge ist aber klar festgelegt:

    1. alte Threads, die durch warte-Aktionen noch laufen
    2. Threads, die durch Auslöser gestartet werden (in Reihenfolge der Auslöser, wie sie im Code auftauchen)
    3. Threads, die von Auslösern gestartet werden. Z.B. Aktion mit Thread-Option oder Auslöser ohne Warte-Option gestartet.
    4. Threads, die eine Wartezeit von "0.0" Sekunden haben. Diese laufen zweimal pro Spiel-Update. Diese Wartezeit schiebt den Thread lediglich ans Ende der Thread-Warteschlange.

    SC2 updated alle Informationen im Spiel 16 mal pro Spielsekunde (-> alle 0.0625 Spielsekunden). Dabei laufen alle Einheitenaspekte ab (schießen, sterben, bewegen, etc) und alle Auslöseraspekte (Auslöser werden gestartet und alle Threads werden weiter abgearbeitet).

    Zitat Zitat von Amorphis Beitrag anzeigen
    Würde ich die besagten Auslöser zusammenfassen oder auch nur ein Teil, anstatt sie nacheinander verkettet ablaufen zu lassen, kommt noch das Problem dazu das hier und da unterschiedliche Bedingungen überprüft werden. Dann hätte ich dadurch einige IF-Anweisungen im Auslöser und der Auslöser wäre insgesamt auch wieder recht lang [...].
    Um lange Auslöser besser lesbar zu machen, sollte man Funktionalitäten in Aktionsdefinitionen verpacken, d.h. der Auslöser selber hat dann fast nur noch die Abfrage.
    Die einfachste Struktur wäre dann:
    -Event
    -Einfache Bedingungen (oder eben gar keine)
    -Aktionen:
    -- IF-THEN-ELSE, bei der dann andere Aktionsdefinitionen gestartet werden, um den Fall zu behandeln, wenn diese mehr Code benötigen. Alle benötigten Informationen sollten dann als Parameter übergeben werden.
    -- weitere Abfragen, um alle Fälle zu behandeln

    Damit du so etwas vielleicht einmal siehst, kann ich dir meine "DialogItem pressed"-Auslöser zeigen:
    http://peeeq.de/gui.php?id=3418
    Dieser Auslöser verarbeitet alle Klicks auf Dialogschaltflächen in meiner Diablo-Map. In den meisten Fällen, wird hier nur die Schaltfäche gesucht und dann eine Aktion zur weiteren Verarbeitung gestartet. Da ich viele Fenster mit vielen Knöpfen habe, ist das alleine schon dementsprechend lang. Aber man sieht, wie ich systematisch überprüfe, welcher Knopf betätigt worden ist. Man könnte dafür jetzt viele, viele Auslöser benutzen (z.B. für jedes Fenster einen, der nur die Schaltfächen im eigenen Fenster übrerprüft), aber es ist halt nur ein Auslöser notwendig und auch optimal.
    Die Resultate des Klicks, wie beispielsweise einen Helm in meinem Diablo-Inventar aufzusetzen, werden dann in vielen weiteren Aktionsdefinitionen verarbeitet. Diese rechnen dann zum Beispiel alle Werte des Helden neu aus, aktualisieren Lebens- und Mana-Anzeigen und überprüfen unnd aktualisieren noch einige andere Dinge wie beispielsweise der Schaden im Tooltip meiner Spells. Ich könnte ja alle diese Dinge in den einen Auslöser schreiben, aber dieser wird dann viele tausend Zeilen lang, weshalb es nur durch Aktionsdefinitionen gelingt, den Auslöser überhaupt zu begreifen.
    meine Diablo1 map
    Ahli: hab nie wc3 gemappt :S bin glatt von scbw zu sc2
    Tomura: oh
    muzzel: OH


    Werbung hält Fanpages am Leben. Bitte deaktiviert Adblock auf den Seiten, die ihr unterstützen wollt.

  5. #5
    Benutzerbild von Amorphis
    Registriert seit
    Jan 2012
    Beiträge
    212
    Likes
    0
    Entschuldige bitte die späte Antwort. Danke für die vielen Informationen, ich denke das wird mir weiter helfen Wenn doch noch neue Schwierigkeiten auftreten werde ich mich hier wieder melden.

Forumregeln

  • Es ist dir nicht erlaubt, neue Themen zu verfassen.
  • Es ist dir nicht erlaubt, auf Beiträge zu antworten.
  • Es ist dir nicht erlaubt, Anhänge hochzuladen.
  • Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
  •