Bits aus Byte-Array extrahieren Alg.

Gast #4609263
Lesenswert?

Hallo zusammen,

ich habe eine Frage bzgl. Algorithmus zum Zerschneiden vom Array. Ich 
habe ein Byte-Array und soll aus dem Array bestimmte Informationen 
rauslesen. Die Informationen sind in dem Byte Array grupiert und ich 
kenne das StartBit und die Länge in Bits. Die extrahierte Bytes/Bits 
soll ich in ein anderes Byte-Array hinkopieren (dsa für die extrahierte 
Länge passt).

Was ist der beste (schnell und optimiert) Algorithmus Eure Meinung nach, 
um diese Aufgabe zu erledigen?

Danke im Voraus für die Antworten
Gast #4609282
Lesenswert?

eben bis jetzt fällt mir nichts vernünftiges ein ;(

habe so gedacht:

startbyte = startbit / 8
startBit  = startbit % 8
endbyte = (startbit + length) / 8
endBit  = (startbit + length) % 8

und dann die grenzeden Byte(s) (start/end) bearbeiten/extrahieren und 
die dazwischen liegende einfach kopieren. Eigentlich, das ist 
Randproblem.

Die Rand-Byte(s) müsste ich mit Shift-Operationen 
rausholen.....hmmmm....Ws meint Ihr?
Gast #4609286
Lesenswert?

Also ohne weitere Informationen wirst du wohl jedes Bit anfassen müssen 
und schauen ob es ein Startbit ist. Bei dieser Ausgangslage vom ersten 
bis zum (letzten-Wortlänge).

Schneller geht es wenn du dein System kennst.
- Kommt das Startbit nur am Anfang eines Bytes (Nur noch jedes 8. Bit 
anfassen) [Wobei sich mir da beim drüber nachdenken gerade die Frage 
aufdrängt wie in einem digitalen System ein StartBIT aussieht]
- Ist es wahrscheinlicher dass es später kommt als direkt am Anfang 
(Startwert der Suche)
- Gibt es andere Muster? Kommt eventuell immer etwas identisches davor?
...

grüße
Gast #4609304
Lesenswert?

mehr Informationen würden mir nicht weiterhelfen. StartBit und Länge 
sind schon ausreichend.

Hier ein Beispiel:

Byte myArray[256]

Gruppe1: StartBit: 0, Länge 20 Bits
Gruppe2: StartBit: 20, Länge 50 Bits
Gruppe3: StartBit: 70, Länge: 100 Bits
....
etc....
#4609316
Lesenswert?

lepper03 schrieb:
> Die extrahierte Bytes/Bits soll ich in ein anderes Byte-Array hinkopieren
> (dsa für die extrahierte Länge passt).

Kann es ja ohnehin nicht, wenn die Gesamtlänge an "Nutzbits" nicht durch 
8 teilbar ist.

D.h. wer auch immer die Daten weiterverarbeitet, wird auch wieder darauf 
schauen müssen und braucht die Zusatzinformation, wieviele Bits denn 
genutzt werden sollen.

> Was ist der beste (schnell und optimiert) Algorithmus Eure Meinung nach,
> um diese Aufgabe zu erledigen?

Ich wüsste nicht, was man da viel optimieren kann. Zumal es vorrangig 
auf die Korrektheit der Ergebnisse ankommt.

Wenn es gerade mal um 256 Bytes geht, die insgesamt zu verarbeiten sind, 
dann dürfte damit so ziemlich jeder Mikrocontroller fix fertig sein. Es 
sei denn die Aufgabe muss Millionen Male pro Sekunde durchgeführt 
werden.
#4609347
Lesenswert?

@OP:

Ohne semantische Zusatzinformationen kann man da konkret kaum was zu 
sagen, wie ein schneller Algorithmus aussehen kann / soll.

Mark Brandis direkt über mir hat schon darauf hingewiesen, dass selbst 
ein verschlafener ATtiny 25 über ein paar paarhundert Bits nur 
schmunzeln würde.

Wenn Du hingegen einen riesigen Datenberg durchzuschaufeln hast, geht 
es, wie auch andere schon geschrieben haben, um Muster, Bedeutung -- 
also Semantik. Wenn die Informationsblöcke immer gleich lang sind und 
nicht 2^(8n) lang sind, also keine n Bytes, sondern irgendwas krummes, 
von mir aus 777 Bits, könnte es allgemein je nach verfügbarem RAM sogar 
angebracht sein, in Assembler oder Low-Level-C über den Speicher zu 
rumpeln, ein Byte/Word/DWord etc. auszulesen, den Inhalt zu kopieren, 
mit Shift-Operationen das Paket rauszuholen (mitlaufender Zähler) und 
aus jedem Bit ein neues Byte(!) zu machen.

Warum? Damit Du danach in einer "vernünftigen" Sprache Deiner Wahl 
(Java(script), C#, Python...) den Verarbeitungsprozess pro Datenblock 
(die angenommenen 777 Bits) auf vielen, vielen Prozessorkernen parallel 
ablaufen lassen kannst. Hier reden wir dann aber schon über echt große 
Datenmengen, die schnell abgearbeitet werden müssen, also von 
irgendeiner Hardware vom Raspi 3 an aufwärts bis zu einem 
ausgewachsenen, massiv-parallelen Cluster. Und sowas ist sogar in C++ 
schon eine ausgesprochen hässliche Angelegenheit, geschweige denn in C 
oder ASM. Als alter "Microsoftie" würde ich das ganze in der 
DotNet-Umgebung laufen lassen (Mono), weil man dort ein echtes 
Schlaraffenland in Sachen Thread-Verwaltung findet, aber ähnliche 
Bibliotheken gibt es bestimmt auch für Java und andere neuere Sprachen.
Gast #4609380
Lesenswert?

Je nachdem wie schlecht dein Compiler ist kann man bei den Divisionen 
und Modulo Operationen schon optimieren --> Shift Operator und logisches 
AND (&).
Das bring aber nur etwas, wenn diese Operationen vergleichsweise oft 
aufgerufen werden, z.B. die Länge der zu extrahierenden Daten kurz ist.
Division und Modulo auf einem Microcontroller ohne Divisions-Einheit 
brauchen da schon mal xx Befehle, um das umzusetzen... einen schlechten 
Compiler vorausgesetzt.

Außerdem könnte man auch Sonderfälle (z.B. Startbit ist durch 8 Teilbar) 
gesondert optimieren.

Wie immer hängt aber die optimale Umsetzung von der Zielplattform ab... 
i7, ARM Cortex, Attiny?? Linux/Windows/C/C++/C#/Java ...

Und die wichtigste Frage ist, ob dieser Algorithmus überhaupt optimiert 
werden muss, oder ob deine Performance eh ganz wo anders verloren geht 
;)
Gast #4609402
Lesenswert?

na ja, wir haben jetzt schon 70% CPU auslastung, dort müssen kritische 
Funktionen berechnet werden. Meine Funktionen sind vielleicht 1% von dem 
ganzen und das Alg. ein sehr kleines Teil von der Funktion, was sagen 
wir 200 mal alle 5 msec aufgerufen wird ;)
#4609411
Lesenswert?

lepper03 schrieb:
> die dazwischen liegende einfach kopieren. Eigentlich, das ist

Und was machst Du, wenn Du ein Byte, bestehend aus 8 Bit von 
Quellposition 0 an Zielposition 1 kopieren sollst?

Dann kannst Du das Byte nicht einfach kopieren.

Lauf durch die Quellbits und kopiere sie einzeln.
Vielleicht reicht Dir die Geschwindigkeit schon.

Geschwindigkeit gewinnen durch das Kopieren von ganzen Bytes kannst Du 
nur dann, wenn Quellposition und Zielposition bei der Division durch 8 
mit Rest im Rest übereinstimmen.

Anstelle über Optimierungen zu sinnen, solltest Du einfach den naiven 
Kopieralorithmus, bzw. die primitive Bitkopierschleife realisieren.

Die Experten hier haben dann bestimmt noch Ideen, wie sich der 
Kopiervorgang des einzelnen Bits beschleunigen lässt.
Gast #4609425
Lesenswert?

Zielposition ist eigentlich einfach, Quellposition 0 an Zielposition 0 
usw.
d.h.
Byte myArray[256]

Gruppe1: StartBit: 0, Länge 20 Bits
Gruppe2: StartBit: 20, Länge 50 Bits
Gruppe3: StartBit: 70, Länge: 100 Bits

Gruppe1 wird einfach an ZielArray1 geschrieben:
ZielArray1[0] = StartBit: 0, Länge 8 Bits
ZielArray1[1] = StartBit: 8, Länge 8 Bits
ZielArray1[2] = StartBit: 16, Länge 4 Bits
....

ok, danke Euch, ich werde mir es jetzt am WE überlegen und mein Ergebnis 
hier posten.
Gast #4610569
Lesenswert?

Mir fällt nichts vernünftiges ein, alles scheint hoch kompliziert zu 
sein :( jemand hat über BitCopyLoop geschrieben, aber wird immer 
kompliziert da man ständig berechnen muss wann neues Byte/Bit im 
QuelleArray endet und wann das neue Byte/Bit im ZielArray anfängt bzw. 
wenn im ZielArray Platz vorhanden ist muss genutzt werden.

Was ich noch machen kann, anstatt es dynamisch zu berechnen, einfach den 
Code zu generieren und im Vorfeld d.h. im Generator schon einige 
Berechnugen vorzubereiten...

Am Anfang habe ich mir gedacht, dass es nicht so schwierig sein kann...
#4610826
Lesenswert?

lepper03 schrieb:
> Mir fällt nichts vernünftiges ein, alles scheint hoch kompliziert zu
> sein :(

Was ist hoch kompliziert? Das was Du hier beschrieben hast:

> startbyte = startbit / 8
> startBit  = startbit % 8
> endbyte = (startbit + length) / 8
> endBit  = (startbit + length) % 8

klingt doch nach einem Ansatz der funktionieren kann, wenn man ihn 
richtig ausprogrammiert.

Ansonsten gilt wie immer:
Teile das zu lösende Problem in kleinere Teilprobleme auf.
#4610896
Lesenswert?

lepper03 schrieb:
> und dann die grenzeden Byte(s) (start/end) bearbeiten/extrahieren und
> die dazwischen liegende einfach kopieren. Eigentlich, das ist
> Randproblem.

Das geht nur in Spezialfällen und klappt im Allgemeinen nicht.

Quelle: Startbit Nr. 4 (die 1!)
Länge: 16

0000 1011   0011 1110 1111

Dann muss das Ziel so aussehen:

1011 0011   1110 1111

Wie Du siehst, kannst Du das das zweite Byte nicht einfach kopieren.

=> Probiere den naiven Algorithmus: Bit für Bit kopieren, also
"Bit einlesen, Bit schreiben"

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren