SetBits / GetBits gut genug?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8677
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von NicTheQuick »

Punkt 7 ist einfach, aber hier absolut fehl am Platz, genauso wie GPU. Die Dateioperationen sind sowieso zig mal langsamer.
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: SetBits / GetBits gut genug?

Beitrag von ccode_new »

@Nic:

Ok! Die Shadervariante wäre trotzdem mal interessant.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8677
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von NicTheQuick »

Das bringt es halt hauptsächlich, wenn man so viele Daten hat, dass sich der Transfer in den Videospeicher der Grafikkarte lohnt und man die Daten dann parallel abarbeiten kann. Das Ergebnis muss man dann ja auch wieder zurück kopieren vom Video-RAM in den normalen RAM.
Bild
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von GPI »

Äh, ich hab eine Frage

Code: Alles auswählen

Case 4;100
      SetBit(*Target,Offset)
ist doch falsch. Man zählt, wie bei allen Zahlen, von rechts nach links, entsprechend ist es offset+2.

Nochwas zu SetBits - das setzt nur Bits, aber löscht nicht, wenn schon was da steht.

Ich würde das simpel so lösen:

Code: Alles auswählen

;PB v.5.62 x64 (Win 7 / 10)

Procedure setbit(*target.integer,bit.i)
  *target\i | (1<<bit)
  ProcedureReturn *target\i
EndProcedure

Procedure GetBit(*target.integer,bit.i)
  ProcedureReturn ( *target\i >> bit) & 1
EndProcedure

Procedure.i SetBits(*Target.integer,Offset.i,Value.i)
  *target\i & ~(%111 << offset) | (value << offset)
  ProcedureReturn *Target\i
EndProcedure

Procedure.i GetBits(*Target.integer,Offset.i)
  ProcedureReturn (*target\i >> offset) & %111
EndProcedure

Global Buffer.i

setbit(@buffer,8)
SetBits(@buffer,2,7)
SetBits(@Buffer,2,4);<- setze den Wert 4 (in 3 Bits) an die Position @Buffer + Offset (in Bits)
Debug GetBits(@Buffer,2);<- hier wird der Wert wieder ausgelesen
Debug Bin(buffer)


For i=0 To 8
  Debug GetBit(@buffer,i)
Next

CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SetBits / GetBits gut genug?

Beitrag von mk-soft »

Mal mit Macros (FastBits)

Code: Alles auswählen

; Fastbits

EnumerationBinary Bits
  #bit0
  #bit1
  #bit2
  #bit3
  #bit4
  #bit5
  #bit6
  #bit7
  #bit8
  #bit9
  #bit10
  #bit11
  #bit12
  #bit13
  #bit14
  #bit15
  #bit16
  #bit17
  #bit18
  #bit19
  #bit20
  #bit21
  #bit22
  #bit23
  #bit24
  #bit25
  #bit26
  #bit27
  #bit28
  #bit29
  #bit30
  #bit31
  #bit32
  #bit33
  #bit34
  #bit35
  #bit36
  #bit37
  #bit38
  #bit39
  #bit40
  #bit41
  #bit42
  #bit43
  #bit44
  #bit45
  #bit46
  #bit47
  #bit48
  #bit49
  #bit50
  #bit51
  #bit52
  #bit53
  #bit54
  #bit55
  #bit56
  #bit57
  #bit58
  #bit59
  #bit60
  #bit61
  #bit62
  #bit63
EndEnumeration


; -------------------------------------------------------------------

Macro Bit(no)
  (1 << no)
EndMacro

; -------------------------------------------------------------------

Macro SetBit(Value, bits)
  Value | Bits
EndMacro

; -------------------------------------------------------------------

Macro ClrBit(Value, bits)
  Value & ~Bits
EndMacro

; -------------------------------------------------------------------

Macro GetBit(Value, bits)
  (Value & Bits)
EndMacro

; -------------------------------------------------------------------

Macro IsBit(Value, bits)
  Bool(Value & Bits)
EndMacro

; -------------------------------------------------------------------

;-Test

var1.i = 1
Setbit(var1, #bit1)
Debug var1

ClrBit(var1, #bit0)
SetBit(var1, bit(3))
SetBit(var1, #bit63)
Debug "Bin : " + Bin(var1)
Debug GetBit(var1, 7)


Debug "IsBit 0 = " + IsBit(var1, #bit0)
Debug "IsBit 1 = " + IsBit(var1, #bit1)

var2.i = 0
SetBit(var2, 7)
ClrBit(var2, %0001)
Debug "var2 = " + var2
Low- HighByte Notation (Mathematisch)

Ich glaube ohne Prozeduren und ohne ASM ist es am schnellsten umgesetzt...
; SetBit(var2, 7)
MOV r15,qword [v_var2]
OR r15,7
MOV qword [v_var2],r15
; ClrBit(var2, %0001)
MOV r15,qword [v_var2]
AND r15,-2
MOV qword [v_var2],r15
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: SetBits / GetBits gut genug?

Beitrag von ccode_new »

Huhu,

ich habe mal ein bisschen mit der GPU gespielt. ;)

Aber die GPU ist für solche Dinge nicht gedacht. (Aber für Bildmanipulation im Allgemeinen schon)

Bei einfachen mathematischen Operationen, oder Bit/Byte - Operationen ist die CPU auch viel schneller als die GPU.

Außerdem (bei mir):
(leider nur float - Unterstützung)
GPUCalc - Error:
"bit-wise operations are forbidden in GLSL 1.10 (GLSL 1.30 or GLSL ES 3.00 required)"

Ich habe mal ein bisschen mit diesem Programm experimentiert:
https://www.rsbasic.de/backupprogramme/GPUCalcNew.zip

Das Ganze muss nur hier:
(Include)
;....
Interface GPUCalcContext
loadCode(index.i, code, length.i)
;...
und hier:
(Test)
If WaitForLastCommand(*context)
*context\loadDataset(0, datatype, *dataset1, elements)
If WaitForLastCommand(*context)
*context\loadDataset(1, datatype, *dataset2, elements)
If WaitForLastCommand(*context)

*context\loadCode(0, Ascii(code), StringByteLength(code, #PB_Ascii))
;...
auf Ascii angepasst werden.

Das Programm habe ich in den Tiefen des PureBasic-Forums gefunden.

Ein Shaderprogramm könnte z.B. so aussehen:
code = "vec4 calc(int startOffset) { return getDataF(0, startOffset) * getDataF(1, startOffset) ; }"

Der erste Parameter wird so:
*dataset1\float[0] = 1
und der zweite so:
*dataset2\float[0] = 3
übergeben.
(und so weiter...)

Anbei: Das ganze ist aber eigentlich schon wieder Offtopic.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

GPI hat geschrieben:

Code: Alles auswählen

Procedure.i SetBits(*Target.integer,Offset.i,Value.i)
  *target\i & ~(%111 << offset) | (value << offset)
  ProcedureReturn *Target\i
EndProcedure

Procedure.i GetBits(*Target.integer,Offset.i)
  ProcedureReturn (*target\i >> offset) & %111
EndProcedure
:allright:
Ich kann zwar noch nicht genau nachvollziehen was hier passiert aber es funktioniert
und ist viel eleganter als mein verrückter SelectCase Code. :mrgreen:
GPI hat geschrieben:Äh, ich hab eine Frage

Code: Alles auswählen

Case 4;100
      SetBit(*Target,Offset)
ist doch falsch. Man zählt, wie bei allen Zahlen, von rechts nach links, entsprechend ist es offset+2.
Binär '100' ist 4 lt. -> https://de.wikipedia.org/wiki/Nibble

________________________________________________________________________

Danke @mk-soft für das Macro Beispiel :D
Leider unterstützt das Beispiel keine Offsets > 63 (da mit einem Integer gearbeitet wird).
Ist es möglich einen *Pointer + Offset (in Bits) and das Macro zu übergeben?

Wie würde der Code von GPI (SetBits / GetBits) als Macro aussehen? :oops:

________________________________________________________________________

@ccode_new
Das mit der GPU ist fur mich zu kompliziert :freak:
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von Sicro »

Mijikai hat geschrieben:Wie würde der Code von GPI (SetBits / GetBits) als Macro aussehen?

Code: Alles auswählen

Macro SetBits(_variable_, _offset_, _value_)
  _variable_ & ~(%111 << _offset_) | (_value_ << _offset_)
EndMacro

Macro GetBits(_variable_, _offset_)
  ((_variable_ >> _offset_) & %111)
EndMacro
Dir ist sicherlich bekannt, dass der PB-Compiler Konstanten beim Compilieren überall durch den Konstanten-Wert ersetzt. So kannst du dir auch die Macros vorstellen: Überall wo ein Macro aufgerufen wird, wird der Macro-Code vom PB-Compiler eingefügt. Es gibt also kein Sprung in ein anderen Kontext, wie es bei Procedures ist. Der PB-Compiler macht also so was ähnliches wie: ReplaceString(Code$, "MacroCommand(...)", MacroCode$).
Der PB-Compiler ersetzt also das hier

Code: Alles auswählen

Define.i settings
SetBits(settings, 2, 1)
durch

Code: Alles auswählen

Define.i settings
settings & ~(%111 << 2) | (1 << 2)
Die Unterstriche sind üblich bei Macro-Parametern, damit sie deutlich unterscheidbar von normalen Variablen sind.

Bei Macros werden Formeln nochmal in Klammern gesetzt, damit die Macros auch innerhalb von Formeln unproblematisch verwendet werden können (die Operatoren-Priorität bleibt erhalten).
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

Sicro hat geschrieben:
Mijikai hat geschrieben:Wie würde der Code von GPI (SetBits / GetBits) als Macro aussehen?

Code: Alles auswählen

Macro SetBits(_variable_, _offset_, _value_)
  _variable_ & ~(%111 << _offset_) | (_value_ << _offset_)
EndMacro

Macro GetBits(_variable_, _offset_)
  ((_variable_ >> _offset_) & %111)
EndMacro
Bin mir nicht sicher ob ich das mit dem Kontext verstanden habe. :|

Momentan operieren die Macros nur auf einer Variable + Offset und somit ist alles auf 8 Bytes limitiert -> maximal SetBits(Variable,63,7).
Ist es möglich das Macro so zu schreiben (evtl. asm) das ich einen *Pointer übergebe damit diese Limitation entfällt?
Da ich kontinuierlich Daten einlesen und so nur das Offset erhöhen müsste.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von STARGÅTE »

Eigentlich gibt es ja schon eine Menge Beiträge zum Thema Bits setzen und lesen:
Structure bitweise füllen / abfragen
einzelne Bits schnell lesen / schreiben
Bit schreiben / lesen
[...]

Wenn es um Geschwindigkeitsoptimierung geht, muss man auch drüber nachdenken, nicht nur einzelne Prozeduren durch Makros zu ersetzen, sonden die Gesamte Zeitintensive Schleife zu optimieren.

Vielleicht kannst du ja einfach mal die gesamte Bearbeitungsschleife posten, damit wie da mal drüber gucken können.
Wie ich das mitbekommen habe geht es um Grauwerte (3 Bit), was schon mal n fürchterliche Anzahl ist.

Was muss denn genau getan werden bei der Verarbeitung ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten