TIA in AWL Array elemente Addieren

Wenn man ohnehin das VerOdern vorzeitig abbrechen möchte, dann kann man sich das VerOdern doch eigentlich ganz ersparen.
Du hast wieder mal recht Heinrich (y)
Jeden Wert auf 0 vergleichen ist effizienter:
Code:
//AWL mit Array-Adressierung (nur mit optimiertem DB?)
// For #i := 50 TO 1 BY -1 DO
      L     50
LOR:  +     -1         //weil Array[0..49]
      T     #i

      L 0.0
      L     "MyDB".RealArray[#i]
      <>R
      SPB   MEND       //Wert <> 0.0 gefunden!

      L     #i
      +     1          //weil Array[0..49]
      LOOP  LOR

      L     0.0
MEND: T     "MyDB".rResult
rResult: Der Code liefert den ersten gefundenen letzten Wert des Arrays, der <> 0.0 ist, oder 0.0 wenn alle Werte 0.0 sind.

Harald

PS: Da sieht man wieder, wie sinnvoll es ist, vorher die Aufgabenstellung exakt zu formulieren und dann auch genau so umzusetzen.
EDIT: Code auf durchgängige Verwendung von Datentyp REAL angepasst
 
Zuletzt bearbeitet:
Mit 50 Real Werten:
AWL optimiert ~8µs
SCL optimiert ~10µs
AWL nicht optimiert ~17µs
Danke für die Zeitmessungen. Könntest Du evtl. auch mal SCL mit nicht optimiertem Speicher messen?

Hast Du den Testcode jeweils in FC verpackt und bei der Zeitmessung auch den Baustein-Aufruf mitgemessen? Wurde da das Array aus einem DB an den Baustein übergeben? Als INPUT oder IN_OUT? All das kann großen Einfluß auf die Ausführungszeit des eigentlichen Codes haben.

Interessant wären auch Vergleiche mit verschiedenen SCL-Compiler-Einstellungen, z.B. ob der erzeugte Code beobachtbar sein soll, oder ENO setzen, oder ARRAY-Grenzen prüfen, oder simulierbar oder welche Optionen es da gibt. Oder welchen Einfluß es hat, wenn man in der Schleife Werte aus einem Global-DB oder aus TEMP oder STAT addiert.

PS: den AWL-Code für "optimiert" kann man noch verbessern, indem man das erhöhen des Index #i und vergleichen auf > 49 anders anordnet und dabei L/T Anweisungen einspart. Und wenn man den Inhalt von AKKU1 um 1 erhöhen will, muß man nicht den Wert 1 laden und dann addieren, sondern kann direkt mit nur einer Anweisung + 1 addieren.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also bei der 1500 werden alle Programmiersprachen direkt in Maschinencode übersetzt. Es dürfte also egal sein, welche Sprache verwendet wird, man sollte deshalb auf Übersichtlichkeit setzen, in Deinem Fall bei 50 Array Elementen addieren in Schleife mit Arrayindex in SCL.

Woher hast du denn die Information über den "Maschinencode"? Laut den Personen welche die Firmware analysiert haben, ist der übersetzte Code für eine virtuelle Maschine die innerhalb einer Sandbox auf den SPS Betriebssystem läuft. Also mindestens 3 Ebenen dazwischen was üblich unter "Maschinencode" verstanden wird. Bei Codesys sieht das anders aus.
 
Laut den Personen welche die Firmware analysiert haben, ist der übersetzte Code für eine virtuelle Maschine die innerhalb einer Sandbox auf den SPS Betriebssystem läuft. Also mindestens 3 Ebenen dazwischen was üblich unter "Maschinencode" verstanden wird.
:unsure: Ach Thomas, könntest Du das bitte so formulieren, dass sich auch ein "normaler" SPS-Programmierer etwas darunter vorstellen kann, der nicht dem Hobby CompilerBau frönt?
Ich deute Deine Worte so, dass der Compiler nicht den bis ins Detail ausgefeilten MaschinenCode eines bestimmten ProzessorTyps "mundfertig" für diesen ProzessorTyp erzeugt, sondern eine Art PseudoCode, der sich zwar sehr eng an MaschinenCodes und Architekturen realer Prozessoren orientiert, der aber letztlich zur Laufzeit doch noch ein Bisschen interpretiert oder sonstwie "überarbeitet" werden muss, um ihn an den realen Prozessor anzupassen.
Oder liege ich mit diesem Verständnis noch ca. 3 (oder mehr?) Ebenen neben dem, was Du gemeint hast? ;)
 
Oder liege ich mit diesem Verständnis noch ca. 3 (oder mehr?) Ebenen neben dem, was Du gemeint hast? ;)
Ich meine das war hier im Forum bei Erscheinen auch schon verlinkt worden:
 
Ach, das wußte ich noch gar nicht. Welche Kunden/Programmierer verlangen denn, daß AWL nur für die S7-1500 noch weiterentwickelt wird/wurde?? Können/wollen die kein SCL oder ist SCL nicht effizient genug?
Warum Siemens das jetzt gemacht hat, weiss ich auch nicht. Jedenfalls ist das aber m.M. einer der ganz wenigen wirklichen Vorteile vom TIA. Im Gegensatz zu den zig Nachteilen 😉
Dadurch kommst Du in AWL jetzt eigentlich so gut wie immer ohne Pointer und ohne absolute Adressierung aus!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Vergleich eines REAL-Wertes auf "gleich 0.0" ist kein Problem. Der Wert 0.0 ist im REAL-Format exakt darstellbar. Problematisch ist höchstens, ob ein Analogeingangswert oder das Ergebnis einer Berechnung exakt 0.0 ergibt. Hier im Thema kommt die 0.0 allerdings durch Kommunikationsausfall als Ersatzwert zustande (alle Bits = 0 ist DW#16#00000000 = REAL#0.0). Da ist der Vergleich auf "gleich 0.0" praktikabel.
Da trau ich dem Frieden perse nicht 😉 Ist wohl ne Berufskrankheit 😂
Wie Du schreibst, es gibt Fälle, wo ein Vergleich auf Gleichheit nicht geht/keinen Sinn hat. Also verbanne ich das generell, dann muss ich nicht ständig drüber nachdenken.
 
Woher hast du denn die Information über den "Maschinencode"? Laut den Personen welche die Firmware analysiert haben, ist der übersetzte Code für eine virtuelle Maschine die innerhalb einer Sandbox auf den SPS Betriebssystem läuft. Also mindestens 3 Ebenen dazwischen was üblich unter "Maschinencode" verstanden wird. Bei Codesys sieht das anders aus.
Irgendwo stand mal in einer Siemens Anleitung, dass bei den 1200 und 1500 SPSen der Code direkt übersetzt wird im Gegensatz zu den 300 / 400, wo FUP und KOP zuerst in AWL und dann in Maschinencode übersetzt werden.
Ich spreche hier von Hardware SPS, Du scheinst laut den Begriffen virtuelle Maschine und Sandbox von einer Software-SPS zu reden. Ob das dort anders ist weiß ich nicht.
 
Ich spreche hier von Hardware SPS, Du scheinst laut den Begriffen virtuelle Maschine und Sandbox von einer Software-SPS zu reden
Nein, Thomas redet davon, was da im Inneren einer Hardware-SPS abläuft.
EX%203.png
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Nochmal kurz Off Topic
Hast Du den Testcode jeweils in FC verpackt und bei der Zeitmessung auch den Baustein-Aufruf mitgemessen? Wurde da das Array aus einem DB an den Baustein übergeben? Als INPUT oder IN_OUT? All das kann großen Einfluß auf die Ausführungszeit des eigentlichen Codes haben.

Interessant wären auch Vergleiche mit verschiedenen SCL-Compiler-Einstellungen, z.B. ob der erzeugte Code beobachtbar sein soll, oder ENO setzen, oder ARRAY-Grenzen prüfen, oder simulierbar oder welche Optionen es da gibt. Oder welchen Einfluß es hat, wenn man in der Schleife Werte aus einem Global-DB oder aus TEMP oder STAT addiert.
Jeder Testcode war sein eigener FC, also wurde der Bausteinaufruf mit gemessen.
Bis auf deinen Baustein, der absolut auf die Arrayelemente zugegriffen hat, wurden das Array als Input übergeben.
Ich bezweifle einen großen Unterschied, da das Array, meines Wissens ohnehin als Pointer übergeben wird.
1680256250768.png

Ob ich mir die verschiedenen Compilereinstellungen mal ansehe, kommt noch auf.

Hier noch eine Momentaufnahme der Messungen:
- 5000 REAL-Werte
- Durchschnitt aus letzten 100 Zyklen
- Einheit µs
1680256524751.png

AWL ist mein alter AWL-Code
AWL2 wäre mit deinen Verbesserungen
Die beiden halten sich aber die Kante. Einmal ist der eine schneller, mal der andere, auch im Durchschnitt.
 
Irgendwie sehe ich keinen Faktor 10 zwischen "optimiert" und "Standard" Speicher ;)
Das kam von mir, und ich habe mir versprochen.
Ich habe ein Faktor 10 gemessen bei pure Boolsche Anweisungen und ein Open Controller welches vermutlich nicht vergleichbar ist mit ein 'standard' CPU.
Ein Faktor 2-3 habe ich gemessen bei gemischte Anweisungen und standard CPU.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte gerne dass batidenko dies probiert:
Die Ausgang NDR (new data received) auf die Receive_P2P Baustein meldet wenn die Daten bereit sind.
Ich habe die Verdacht dass dies erledigt das Problem ohne dass man die AWL oder SCL code superoptimieren muss.
 
Nochmal kurz Off Topic

Jeder Testcode war sein eigener FC, also wurde der Bausteinaufruf mit gemessen.
Bis auf deinen Baustein, der absolut auf die Arrayelemente zugegriffen hat, wurden das Array als Input übergeben.
Ich bezweifle einen großen Unterschied, da das Array, meines Wissens ohnehin als Pointer übergeben wird.

Zu dem Tests gehören dann auch noch Informationen über:
- Ablageort der Daten im DB, optmiert oder nicht optimiert? Wenn alles "nicht optimiert" ist, dann muss imho die Endianess bei reinen Kopiervorgängen nicht angepasst werden. Erst bei arithmetischen Operationen ist das notwendig
- Ist der gesamte FC in einer Sprache erstellt (z.B. in SCL), oder ist das ein KOP/FUP FC mit Netzwerken in SCL?
- Option ENO setzen aktiv? Hängt mit dem obigen Punkt zusammen, denn ich meine bei einem SCL Netzwerk in einem FUP/KOP Baustein ist der SCL Code entsprechend eines einzelnen Bausteins mit gesetzter ENO Option. Das führt dann im Vergleich zu AWL zu vermeintlich langsameren Code, aber der kann dann eben auch mehr als der AWL Code und ist somit nicht vergleichbar.
 
Zurück
Oben