Ja, leider ... muss jedes Bit einzeln setzen ... langer (Un-)Sinn, kurze Erklärung:Thorium hat geschrieben: Musst du wirklich jedes Bit einzeln setzen?
Schreib doch mal was genau dein Ziel ist.
ich bekomme von einer externen Lib (Eine Art Wrapper-DLL für eine spezielle I/O Karte) ein Bit mit Zeitstempel.
Es werden Signale von 128 externen MicroControllern mit je ca. 500 Sensoren (nur Ja/Nein) gesendet.
Diese Daten muss ich Sortieren und da auch viel Parallel gearbeitet wird (Threads), muss jedes Bit einzeln geschrieben werden.
Könnte sie auch in einem Puffer sammeln, aber da hätte ich das gleiche Problem.
Das ganze geht teilweise über ein paar Stunden ... brauche dafür dann auch geschätzt 30 GB RAM.
Habe mich jetzt Entschieden, doch Makros zu benutzen, auch wenn ich versuche sie zu meiden. Für meinen Geschmack etwas zu Fehleranfällig.
Wollte sie als "Funktionsersatz" schreiben, mit halbwegs vernünftigem Rückgabewert (deshalb das Bool() macht auch kaum einen Unterschied bei der Geschwindigkeit). Scheinbar ist der Overhead von Proceduren für diese Aufgabe doch zu groß. Mit Makros läuft es noch um einiges schneller.
BitWrite wäre ohne "If, Else" ganz gut ... aber da gibt es ein kleines Problem. Es funktioniert zwar so, ABER ... ich kann nur Konstanten angeben.
Wieso das BitArray? Kann man nicht einfach einen Pointer "hochzählen" ... steht auch so in der Hilfe. Und bei dem Beispielcode unten funktionierts auch.CSHW89 hat geschrieben:... oder dann als Macro-Variante (dann muss aber gewährleistet sein, dass der Parameter _var_ auch in der aufrufenden Procedure ein Pointer vom Typ BitArray ist

Folgenden Code habe ich jetzt "Zusammengetragen":
Code: Alles auswählen
EnableExplicit
DisableDebugger
Macro SetBit(_ptr_, _pos_)
Bool(PokeB(_ptr_ + _pos_ >> 3, PeekB(_ptr_ + _pos_ >> 3) | 1 << (_pos_ & 7)))
EndMacro
Macro ClearBit(_ptr_, _pos_)
Bool(PokeB(_ptr_ + _pos_ >> 3, PeekB(_ptr_ + _pos_ >> 3) & ~(1 << (_pos_ & 7))))
EndMacro
Macro ToggleBit(_ptr_, _pos_)
Bool(PokeB(_ptr_ + _pos_ >> 3, PeekB(_ptr_ + _pos_ >> 3) ! (1 << (_pos_ & 7))))
EndMacro
Macro GetBit(_ptr_, _pos_)
Bool(PeekB(_ptr_ + _pos_ >> 3) & 1 << (_pos_ & 7))
EndMacro
Macro WriteBit(_ptr_, _pos_, _value_ = 1)
Bool(PokeB(_ptr_ + _pos_ >> 3, PeekB(_ptr_ + _pos_ >> 3) | (PeekB(_ptr_ + _pos_ >> 3) ! (-_value_ ! PeekB(_ptr_ + _pos_ >> 3)) & (1 << (_pos_ & 7)))))
EndMacro
Macro ReadBit(_ptr_, _pos_) ; ein WriteBit braucht ein ReadBit ;-)
GetBit(_ptr_, _pos_)
EndMacro
#memspace = 1000000
Define *test = AllocateMemory(#memspace)
Define i
Define test1start = ElapsedMilliseconds()
For i = 0 To MemorySize(*test) * 8 - 1
;SetBit(*test, i)
;If Mod(i,2) : ToggleBit(*test, i) : EndIf
WriteBit(*test, i, i % 2) ; "Ausdruck ist zu komplex (CPU-Register reichen nicht). Bitte splitten SIe ihn" o.O
Next
Define test1endtest2start = ElapsedMilliseconds()
For i = 0 To MemorySize(*test) * 8 - 1
GetBit(*test, i)
Next
Define test2end = ElapsedMilliseconds()
MessageRequester("Bit-Test", "MBit Gesamt: " + StrF(MemorySize(*test) * 8 / 1000000) + Chr(13) + "Schreiben: " + Str(test1endtest2start - test1start) + " ms" + Chr(13) + "Lesen: " + Str(test2end - test1endtest2start) + " ms"+ Chr(13) + "BitRW/s: " + Str(MemorySize(*test) * 8 / (test2end - test1start) * 1000))