Ein kleines Code - Schnippsel um automatisch Cache - Tabellen für statische Funktionen anzulegen, also Funktionen die auf denselben Übergabe - Parameter immer denselben Wert zurückgeben. Typisch für Sinus/Cosinus usw. Tabellen um Spiele zu beschleunigen damit die Funktion nicht jedesmal berechnet werden muss, oder auch für eigene Funktionen. Der Code erstellt ein Macro um den Funktionsaufruf der jeweiligen Funktion automatisch so umzubiegen das die Cache - Table benutzt wird, also sehr leicht in bestehenden Source zu integrieren. Des weiteren gibt es Macros um die Umleitung zu aktivieren und deaktivieren.
z.B:
Code: Alles auswählen
cachetable_create(sin, -#PI, #PI, 10000)
Per cachetable_disable(sin) kann diese Umleitung ausgeschalten werden, es wird wieder die orginale PB - Sin Funktion verwendet. Analog per cachetable_enable(sin) wieder aktiviert.
Der Tabellen - Generator erhöht die Anzahl von Slices automatisch auf eine 2. Potenz um die Bereichsprüfung effizient per Bitoperation durchzuführen. Des weiteren erhöht er die die Anzahl der Slices automatisch um im gewählten Bereich das beste Sigma zu finden (können auch 4,5 2. Potenzen sein oder keine, je nach Funktion/Bereich). cachetable_sigma(function) gibt automatisch das aktuelle sigma für die jeweilige Funktion an. (Die durchschnittliche Abweichung zwischen der echten Funktion und den zwischengespeicherten Werten)
Code: Alles auswählen
; EnableExplicit
CompilerIf #PB_Compiler_Version < 510
; Wir benötigen "UndefineMacro"
CompilerError "Minimum supported Version: PB 5.10"
CompilerEndIf
CompilerIf Not Defined(__macrobuilder, #PB_Constant)
#__macrobuilder = #True
Macro _Macro1
M
EndMacro
Macro _Macro2
acro
EndMacro
Macro _Macro
: _Macro1#_Macro2
EndMacro
Macro _EndOfMacro1
EndM
EndMacro
Macro _EndOfMacro
: _EndOfMacro1#_Macro2
EndMacro
CompilerEndIf
; Logarithmus zur basis 2 (binärlogrithmus)
CompilerIf Not Defined(_1dLN_2, #PB_Constant)
#_1dLN_2 = 1.4426950408889634074
Macro ld(x)
(Log(x)*#_1dLN_2)
EndMacro
CompilerEndIf
; Schaltet Cache - Table ein
Macro cachetable_enable(func)
CompilerIf Defined(__cachetable_#func#, #PB_Array)
_Macro func#(_t)
__cachetable_#func#(Int(((_t)-__table__start_#func)*__table__part2_#func)&__table_stepsreal_#func)_EndOfMacro
:CompilerEndIf
EndMacro
; Schaltet Cache - Table ab
Macro cachetable_disable(func)
CompilerIf Defined(__cachetable_#func#, #PB_Array)
UndefineMacro func
CompilerEndIf
EndMacro
Macro cachetable_sigma(func)
__table_sigma_#func
EndMacro
Macro cachetable_steps(func)
__table_stepsreal_#func
EndMacro
; Erstell Cache - Table
Macro cachetable_create(func, area_start, area_stop, steps = 4095, type = f, maxbitadd = 3)
CompilerIf Not Defined(__cachetable_#func#, #PB_Array)
Define.i __table_bits_#func = Int(Round(ld(steps), #PB_Round_Up))
Define.i __table_bitsused_#func = __table_bits_#func-1
Define.type __table_sigmaold_#func
Define.i __table_lastcalc_#func = #False
Global.type __table_sigma_#func
If __table_bitsused_#func>31
__table_bitsused_#func = 31
EndIf
Repeat
__table_sigmaold_#func = __table_sigma_#func
If __table_lastcalc_#func
__table_bitsused_#func - 1
Else
__table_bitsused_#func + 1
EndIf
; Werte Berechnen...
Global.i __table_stepsreal_#func = Int(Pow(2, __table_bitsused_#func))-1
Define.type __table__stop_#func = Abs((area_stop)-(area_start))
Define.type __table__part_#func = __table__stop_#func/__table_stepsreal_#func
Global.type __table__part2_#func = __table_stepsreal_#func/__table__stop_#func
Global.type __table__start_#func = (area_start)
Define.type __table__cur_#func = (area_start)
Define.i __table__cnt_#func = 0
Global Dim __cachetable_#func#.type(0)
ReDim __cachetable_#func#.type(__table_stepsreal_#func)
; Cached Werte
While __table__cnt_#func < __table_stepsreal_#func
__cachetable_#func#(__table__cnt_#func+1) = func#(__table__cur_#func)
__table__cur_#func + __table__part_#func
__table__cnt_#func + 1
Wend
; Sigma Minimieren
If Not __table_lastcalc_#func
__table__cnt_#func = 0
__table_sigma_#func = 0
While __table__cnt_#func < (__table_stepsreal_#func*2)
Define.type __table__tval_#func = (__table__cnt_#func/(__table_stepsreal_#func*2))*__table__stop_#func + __table__start_#func
__table_sigma_#func + (func#(__table__tval_#func) - __cachetable_#func#(Int(((__table__tval_#func)-__table__start_#func)*__table__part2_#func)&__table_stepsreal_#func))
__table__cnt_#func + 1
Wend
__table_sigma_#func = Abs(__table_sigma_#func/(__table_stepsreal_#func*2))
Else
Break
EndIf
; Neues Sigma schlechter als letztes...
If (__table_sigmaold_#func < __table_sigma_#func) And (__table_bitsused_#func <> __table_bits_#func)
__table_lastcalc_#func = #True
__table_sigma_#func = __table_sigmaold_#func
ElseIf (__table_bitsused_#func = 32) Or (__table_bitsused_#func = (__table_bits_#func+maxbitadd)) ; Mehr geht nicht!
Break
EndIf
ForEver
; cachetable activate
cachetable_enable(func)
CompilerEndIf
EndMacro
Macro cachetable_default(steps = 4095)
cachetable_create(sin, -#PI, #PI, steps, f)
cachetable_create(cos, -#PI, #PI, steps, f)
cachetable_create(tan, -#PI, #PI, steps, f)
cachetable_create(asin, -1, 1, steps, f)
cachetable_create(acos, -1, 1, steps, f)
cachetable_create(atan, -1, 1, steps, f)
EndMacro