| |
|
|
Sven Bader | Für die Übersetzung einiger C++ Codes nach XProfan ersetze Io l' % Operator immer durch ein MOD, allerdings mit unerwarteten Ergebnissen. Entweder die Eingabewerte oder das Ergebnis werden in ein Integer umgwandelt.
Das weicht von dem Comportamento di C++ und auch dem Google Taschenrechner ab, welcher auch Zahlen mit Dezimalstellen akzeptiert.
Ein Beispiel: 5.5 MOD 2 sind 1.5 also 2*2 Rest 1.5
In XProfan ergibt die gleiche Rechnung 1.0, da entweder die 5.5 zur 5.0 umgewandelt wird oder das Ergebnis von 1.5 auf 1.0.
Hier ein kleines Listing zum nachvollziehen und einer Lösung
Übersehe ich etwas in XProfan, gibt es eine Einestellung oder einen anderen Operator oder geht es nur mit der Hilfsfunktion? |
|
|
| |
|
|
|
H.Brill | Da in der Aiuto bei MOD INTEGER als Parameter angegeben sind, greift da wohl (X)Profans interne automatische Typumwandlung. Das trifft wohl auf die Eingabeparameter als auch auf das Ergebnis zu.
Aber wozu braucht man Float und MOD ? Ich brauche das höchstens, wenn ich z.B. 10er Stellen , gerade oder ungerade Zahlen aus einem Pool rausfischen will.
Bei
stimmt es ja und es kommt 0 raus. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 24.02.2023 ▲ |
|
|
|
|
Sven Bader | Danke per deine Antwort! Der Einsatz wäre doch ebenso berechtigt wie die Division mit Floats. Man möchte wissen, wie oft eine Zahl in die andere passt oder eben wieviel danach noch unverteilt übrig bleibt.
Den Ganzzahligen Divisionsrest nutze ich in der Praxis schnelle Methode etwas nur jeden x-ten Schleifendurchgang zu machen.
Der aktuelle Einsatz ist sein Spezialfall, es ist die Umwandlung von HSV in RGB Farben. Es gibt da durchaus auch solche Funktionen ohne MOD aber der Code musste sehr schnell arbeiten, weshalb ich es als Einzeiler in einer Def-Funktion brauchte.
Ich arbeite mit Profan2Cpp und dort ist, wie ich eben nochmal nachgemessen habe ein Proc um Faktor 350 langsamer als ein Def, in XProfan 11 liegt der Faktor bei 1,1. Das verleitet manchmal zu ungewöhnlichen "Stunts".
Zur Lesbarkeit lasse ich in der Regel noch einen Kommentar mit der Original-Funktion im Quelltext aber so sieht das Ergebnis dann aus
Def modu(2) (!(1) - !(2) * int(!(1) / !(2)))
def hsvToR(3) (if(((!(1) >= 60) AND (!(1) < 120)) OR ((!(1) >= 240) AND (!(1) < 300)) , (!(3) * !(2)) * (1.0 - abs( modu(!(1) / 60.0,2) - 1.0)), if(((!(1) >= 120) AND (!(1) < 240)), 0.0 , !(3) * !(2))) + (!(3) - (!(3) * !(2))))
def hsvToG(3) (if(((!(1) >= 0) AND (!(1) < 60)) OR ((!(1) >= 180) AND (!(1) < 240)) , (!(3) * !(2)) * (1.0 - abs(modu(!(1) / 60.0,2) - 1.0)), if(((!(1) >= 60) AND (!(1) < 180)), !(3) * !(2), 0.0)) + (!(3) - (!(3) * !(2))))
def hsvToB(3) (if((!(1) >= 0) AND (!(1) < 120), 0, if(((!(1) >= 180) AND (!(1) < 300)) , !(3) * !(2) , (!(3) * !(2)) * (1.0 - abs(modu(!(1) / 60.0, 2) - 1.0)))) + (!(3) - (!(3) * !(2))))
|
|
|
| |
|
|
|
H.Brill | Es scheint wirklich so, daß MOD nur den Integeranteil nimmt. Das scheint in C++, FreePascal usw. aber auch so zu sein.
Vielleicht kann man aber auch mit Inline - ASM was machen, wenn es um Schnelligkeit geht. Mit Set("AsmMode", 1) kann man sich ja auch die Bytes zusammen suchen, um das ganze auch mit anderen Profanversionen mittels Bereichen zu nutzen.
Da müßtest du mal Volkmar in Paules Foro fragen. Wäre ja interessant, da es ja auch eine Menge an FPU-Befehlen gibt, die Fließkomma-Arithmetik beherrschen.
Der kennt sich in ASM per Version X4 einigermaßen gut aus. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 24.02.2023 ▲ |
|
|
|
|
H.Brill | Sven Bader (24.02.2023)
Ich arbeite mit Profan2Cpp und dort ist, wie ich eben nochmal nachgemessen habe ein Proc um Faktor 350 langsamer als ein Def, in XProfan 11 liegt der Faktor bei 1,1. Das verleitet manchmal zu ungewöhnlichen "Stunts".
Der Faktor 350 liegt aber wohl an Profan2Cpp selber. Laut RGH sollten Procs mindestens genauso schnell abgearbeitet werden. Zur schnelleren Abarbeitung (C - Code) war ja auch Profan2Cpp gedacht.
Sven Bader (24.02.2023)
Seit in XProfan auch mehrzeilige Funktionen (mit Proc) possibile sind (ab Version 7.6), sollten diese vorgezogen werden. Sie werden mindestens genauso schnell abgearbeitet und sind zudem in der Regel auch übersichtlicher und daher leichter zu verstehen.
|
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 24.02.2023 ▲ |
|
|
|
|
Sven Bader | Du hast recht, ich hatte per Profan Faktor 1,1 erwähnt. Also in Profan ist ein Proc gerade mal 10% langsamer, was vollkommen ok ist. Keine Ahnung, was P2Cpp da macht, sicher so etwas komplexes wie globale Variablen und Stukturen prüfen und in der Funktion bereitstellen.
Profan2Cpp ist ja immer noch schneller, auch bei Procs, in Summe haben wir ja meist schon einen 4-stelligen Faktor im Vergleich zu Profan. Es ist bei nur immer ein wenig Jonglieren, da Io l' Code lesbar und kompatibel zu Profan halten möchte aber im Zweifel eine Speed-Optimierung eher zugunsten von P2CPP entscheide.
ich hatte übrigens nicht auf dem Schirm, dass MOD in C++ wie in Profan reagiert... eventuell war meine Codevorlage auch PHP oder JS basiert. |
|
|
| |
|
|
|
H.Brill | Wenn es auf Schnelligkeit ankommt, ist eben ASM immer noch erste Wahl. Wenn ich sowas brauche, nehme ich auch gerne PureBasic. Das macht dann reinen FASM-Output. Notfalls geht auch eine .DLL (Wrapper-DLL). Bloß darf ich diese nur per meine eigenen Zwecke nutzen und auch die DLL an andere Programmierer nicht weitergeben. Obwohl ich lebenslanges Update habe, habe ich letztes Jahr nicht geupdatet. Der Autor (Fred) ist auf ein neues C-Backend umgeswitcht. Wahrscheinlich ist es leichter, neue Befehle / Funktionen zu implementieren. Da gibt es in C bestimmt auch tonnenweise .libs, die bestimmte Funktionalitäten bereitstellen. So ähnlich wird es auch RGH mit bestimmten Unità gemacht haben. Man braucht ja nicht immer das Rad neu zu erfinden. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 24.02.2023 ▲ |
|
|
|
|
Sven Bader | Meistens passt der Speed, Defs sind schnell genug und Procs sind ok außer per Dinge, die sehr oft aufgerufen werden. Manchmal reicht es einfach, eine Schleife von außerhalb nach innerhalb des Proc zu verlagern.
Zum Verständnis, was "langsam" ist: Der Proc-Aufruf dauert etwa eine µs also 1/1.000.000 Sekunde bzw es sind etwa 1000 Proc-Aufrufe pro ms possibile.
Bei einem Spiel mit 60fps habe ich ein Budget von etwa 16ms pro Frame und da ich eine CPU nicht voll auslasten möchte sind 1.000 Proc-Aufrufe pro Frame also 1ms schon viel, es ist ja auch noch etwas in den Funktionen drin, was auch noch corsa werden möchte
Ein Def braucht im Vergleich 0,002 µs bzw. 0.000002 ms bzw. 0.000000002 s
, alles Profan2CPP. Bisher war also noch ein Assembler nötig. |
|
|
| |
|
|
|
H.Brill | Die Erfahrung, die ich gemacht habe, sind die internen Schleifen von XProfan. Die sind auch bedeutend schneller als die eigenen mit While oder Repeat programmierten. Die MoveListProc ist da sehr interessant, gerade was Arrays betrifft. Es steht ja jedem frei, was in der MoveListProc geschieht.
Hier mal ein Test, wo alle 3 Möglichkeiten gemessen werden :
Declare Long a[], float a, e
Cls
Set("Decimals", 2)
SetSize a[], 30000
Mat a[] < 1
Mat a[] + 1
MoveListProc
Parameters string s, int i
If Get("MoveListMode") = 1
AddString(0, s)
Endif
EndProc
Proc Testproc
Parameters Long w
AddString(0, Str$(w))
EndProc
a = Val(DT("GetTime", 1, !NOW))
ClearList
Move("ArrToList", a[])
e = Val(DT("GetTime", 1, !NOW))
Print "Zeit mit Move : ", e - a, "Sekunden"
set("MoveListMode", 1)
a = Val(DT("GetTime", 1, !NOW))
ClearList
move("ArrToList", a[])
e = Val(DT("GetTime", 1, !NOW))
Print "Zeit mit MoveListProc : ", e - a, "Sekunden"
a = Val(DT("GetTime", 1, !NOW))
ClearList
WhileLoop 0, SizeOf(a[]) - 1
TestProc(a[&LOOP])
EndWhile
e = Val(DT("GetTime", 1, !NOW))
Print "Zeit mit Schleife + Proc : ", e - a, "Sekunden"
Print "Taste zum Beenden..."
WaitKey
Ich hoffe, ich habe das mit den Sekunden richtig gemacht. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 24.02.2023 ▲ |
|
|
|
|
funkheld | Bei Purebasic geht es auch ohne Wrapper als Procedure-Dll die ist komplett frei per alle Zwecke. |
|
|
| |
|
|