Beim Byte die Bits am schnellsten umsetzen.

Gast #6871699
Lesenswert?

Peter B. schrieb:
> Wie kann man bitte ein Byte : 11000001 am schnellsten umsetzen
> nach : 10000011 mit Schieben, AND , Or usw?

mit dem passenden Maschinenbefehl" 'reverse (Address-) bit order'
DSP haben einen solchen Befehl, weil er den Butterfly-FFT Algo immens 
beschleunigt. In den PC-x86 addresssatz könnte man sowas auch in den 
MME-Teil o.ä. finden.
Gast #6871813
Lesenswert?

Peter B. schrieb:
> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.

Du hast nach der schnellsten Methode gefragt und das ist zweifelsohne 
eine Tabelle, wenn man man mal von festverdrahteter Logik absieht. Das 
ist kein Krampf, sondern straight forward - direkter geht es nicht.
#6871815
Lesenswert?

Wolfgang schrieb:
> direkter geht es nicht

Doch. Bitreverse geht direkter und schneller - wenn als Befehl vorhanden 
und genau das gewünscht ist. Tabelle hat demgegenüber den Vorteil, trotz 
vage formulierter Frage auf jedem Prozessor für jede Permutation 
geeignet zu sein. Daher ist die Tabelle die schnellere Antwort auf die 
Frage, aber nicht unbedingt das zur Laufzeit schnellere Verfahren.
#6871853
Lesenswert?

Jens B. schrieb:
> Das muss nicht sein. Es gibt auch Befehle, die sind schneller wenn man
> die per hand bastelt statt dem fertigen Befehl, bei x86 war es beim loop
> befehl so, afaik.

Im Prinzip richtig, aber kennst du einen Prozessor mit 
Bitreverse-Befehl, der sich dafür dementsprechend viel Zeit lässt?

Beim LOOP war es auch schon so, dass der vorsätzlich ausgebremst 
wurde, damit ein herzallerliebstes Betriebssystem überhaupt bootete. ;-)
Gast #6871910
Lesenswert?

(prx) A. K. schrieb:
> Wolfgang schrieb:
>> direkter geht es nicht
>
> Doch. Bitreverse geht direkter und schneller - wenn als Befehl vorhanden
> und genau das gewünscht ist.

Bei divesren ARM's könnte RBIT das gesuchte sein: 
https://developer.arm.com/documentation/dui0802/a/A32-and-T32-Instructions/REV--REV16--REVSH--and-RBIT

Oder man hat programmierbare Logik und bastelst sich diese Instruction 
aus ein bißchen routing ressourcen und FF.

Und natürlich stellt sich die Frage, wie man das transponierte 
weiterverwenden will, alls addresspointer braucht man es nicht extra 
drehen sondern könnte es beim TMS320 direkt zu bit reversal addressing 
verwenden.

Aber das wurde, wie gesagt, hier schon mal durchgekaut, mehr als einmal.

> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
Das ist kein Krampf , das ist ganz simples bitschubsen. Wenn das zuviel 
für Deine Computerfähigkeiten ist, könntest du dir ja was weniger 
Anspruchsvolles als Freizeitbeschäftigung aussuchen.
Gast #6872088
Lesenswert?

Peter B. schrieb:
> Wie kann man bitte ein Byte : 11000001 am schnellsten umsetzen
> nach : 10000011 mit Schieben, AND , Or usw?

Welche CPU?

Früher wurden noch die Bios-Befehle benutzt, und da hätte man wohl AND 
und/oder je nach Vorfall OR genommen - aber der Rotationsbefehl einmal 
bzw. zweimal (über das Carry-Flag) nach links geht natürlich auch, nur 
war der früher etwas langsam.
Dafür isser aber für die Ausgabe der Bits sehr praktisch.

https://www.i8086.de/asm/8086-88-asm-rcl.html

https://www.davespace.co.uk/arm/introduction-to-arm/barrel-shifter.html
Gast #6872138
Lesenswert?

Peter B. schrieb:
> Danke für die Info.
>
> Wusste nicht , das es so ein Krampf ist mit den Bit im Byte zu tauschen.
>
> Wir fliegen zum Mond und schreiben Bücher über dieses Bit im Byte
> tauschen.... hm

Das sind Fingerübungen. Wenn sowas öfter gebraucht würde, würde es dafür 
ein Modul geben. Ich hätte es einmal gebraucht. Der Prozessor konnte es 
sogar (mirror), aber es lohnte nicht den Aufwand, da einen 
Assembler-Befehl einzufügen.
Gast #6872647
Lesenswert?

Normalerweise bin ich ja kein fan von bitfields, aber bits reversen ist 
lästig. Da würde ich die dann doch nehmen, und das Optimieren dem 
Compiler überlassen:
https://godbolt.org/z/dP6T837nq
1
#include <stdint.h>
2
#include <string.h>
3
#include <assert.h>
4

5
static inline uint8_t bit8_reverse(const uint8_t u8){
6
  struct __attribute__((packed)) b8 {
7
    unsigned b0 : 1;
8
    unsigned b1 : 1;
9
    unsigned b2 : 1;
10
    unsigned b3 : 1;
11
    unsigned b4 : 1;
12
    unsigned b5 : 1;
13
    unsigned b6 : 1;
14
    unsigned b7 : 1;
15
  };
16
  static_assert(sizeof(struct b8) == sizeof(uint8_t));
17
  struct b8 in;
18
  memcpy(&in, &u8, 1);
19
  const struct b8 out = {
20
    .b0 = in.b7,
21
    .b1 = in.b6,
22
    .b2 = in.b5,
23
    .b3 = in.b4,
24
    .b4 = in.b3,
25
    .b5 = in.b2,
26
    .b6 = in.b1,
27
    .b7 = in.b0,
28
  };
29
  uint8_t res;
30
  memcpy(&res, &out, 1);
31
  return res;
32
}
Gast #6872800
Lesenswert?

🐧 DPA 🐧 schrieb:
> Wow, tatsächlich. Es nutzt rbit:
> https://godbolt.org/z/c4ozsvP3otest:
> // @test
>         rbit    w8, w0
>         lsr     w0, w8, #24
>         ret
>
> Zwar nur bei recht aktueller clang Version, aber trotzdem. Da sieht man
> mal wieder, heute noch selber Assembler schreiben bringts nicht mehr.

Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart 
man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das 
C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen 
umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen 
genutzten Compilerschaltern, Mandphasen etc. pp. .

Zum Kellnern sagt man ja auch "Bringens mir bitte ein halbes Hefeweiße" 
und setzt nicht zu einem verquasten Vortrag über seine aktuelle 
Befindlichkeit bezüglich Kaltgetränke an, um ne Viertelstunde später den 
Kellner wieder zurückzuschicken, weil er ein veganes  Alkoholfreies 
gebracht hat.
Falls man seine Ansprache überhaupt an den richtigen Kellner gerichtet 
hat und nicht an einen Touristen, der sich aus Unkenntnis der 
Alltagsgebräuche wie ein Lokalkellner gekleidet hat.
(Firma: S-C-I DATA GbR) #6872814
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:
> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart
> man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das
> C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen
> umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen
> genutzten Compilerschaltern, Mandphasen etc. pp. .

Da bin ich ganz deiner Meinung. ;-)
Moderator Persönliche Seite #6872830
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:
> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart
> man sich die 30 zeilen C-Code

Spätestens beim Port auf einen anderen µC bist Du aufgeschmissen. Der 
C-Code jedoch funktioniert mit allen µCs. Und dort wird er möglichst 
optimal übersetzt.

Als C-Programmierer machst Du 30 Ports mühelos mit, als 
Assembler-Programmierer musst du einfach aufgeben.
Gast #6872849
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:
> Doch, wenn man selbst die 3 Zeilen Assembler als inline hintippt, spart
> man sich die 30 zeilen C-Code und die Überprüfung ob der C-Compiler das
> C-Construct erkennt und wie gewünscht in die drei Assembler Zeilen
> umsetzt. Und er das immer tut und nicht abhängig wegen irgendwelchen
> genutzten Compilerschaltern, Mandphasen etc. pp. .

1. Der C-Code funktioniert auf so ziemlich allen Platformen. Die meisten 
davon haben keine rbit Instruktion.

2. Ich wusste gar nicht, dass ARMv8 diese Instruktion besitzt. Bis ich 
mir alle Instruktionen nochmal durchgesehen habe, um mir zu überlegen, 
wie ich das am besten mache, habe ich den C Code schon längstens 
eingetippt. Der C Code ist auch absolut trivial und einfach zu 
verstehen. Da sieht man sofort, was er macht. Das man etwas mehr 
Eintippt ist doch egal.

3. Ich muss nicht nachschauen, wie gut der Compiler das optimiert. Dass 
kann mir erstmal egal sein. Wenn etwas zu langsam ist, nehme ich den 
Profiler raus. Und wenn der anzeigt, dass diese Funktion am meisten zeit 
verschwendet, erst dann lohnt es sich, überhaupt über das Optimieren 
nachzugenken.

4. Der Compiler kann das sehr wohl inlinen. Das hat er bei der Funktion 
test() auch gemacht. Aber auch ohne das static inline kann und tut der 
Compiler inlinen, wenn sinvoll.

5. Punkto Stabilität, ok, der Code könnte sich ändern. Ich habe aber 
noch nie gesehen, dass er mit neueren Compilern verschlechtern würde. 
Wenn man das wirklich unbedingt verhindern muss / will, warum auch 
immer, gibt es mehrere Möglichkeiten. Entweder, man legt einfach fest, 
welchen Compiler man verwenden soll (also Version, Build, usw.). Oder 
man packt sich die guten Assembler Versionen irgendwo hin, und lässt die 
die C Versionen ersetzen (beim build), sofern man die für die Plattform 
hat. (Aber dann auch immer reine C Builds testen,  damit man die 
Originale nicht versehentlich mal löscht, und später wieder suchen 
muss).

So oder so, kein Grund sich selbst anstrengen & mit ASM abmühen zu 
müssen.
Gast #6872853
Lesenswert?

Frank M. schrieb:
> Als C-Programmierer machst Du 30 Ports mühelos mit,
Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen ob er 
wirklich die gewollte optimale Assembler-Variante generiert hat.

> Assembler-Programmierer musst du einfach aufgeben.
Also Programmierer steht man über die infantilen Streiteren ob 
assembler oder C der 'Heilige Scheiß' sei und verlässt sich nicht auf 
die maschinelle (Un-)Intelligenz) eines Compilers.
Und auch als Programmierer der den befehlssatz und CPU-Architekturen 
beherrscht,  ist man nicht gezwungen alles in Assembler-Mnemonics  zu 
schreiben, sondern kann ganz profesionell, inline Assembler verwenden, 
wo er gegenüber Compiler-hHrsteller spezifischen C-Konstrukten 
effizienter und schneller ist.

Man will ja schliesslich 'Computer beherschen' und nicht als 
'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.
Gast #6872879
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:
> Frank M. schrieb:
>> Als C-Programmierer machst Du 30 Ports mühelos mit,
> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen ob er
> wirklich die gewollte optimale Assembler-Variante generiert hat.

1. Warum musst du das machen?

2. Kennst du immer die optimale Lösung?

Assembler gehört zum Handwerkszeug schrieb:
> sondern kann ganz profesionell, inline Assembler verwenden,
> wo er gegenüber Compiler-hHrsteller spezifischen C-Konstrukten
> effizienter und schneller ist.

Wie würdest du die rbit Variante vom Compiler effizienter gestalten?

Assembler gehört zum Handwerkszeug schrieb:
> Man will ja schliesslich 'Computer beherschen' und nicht als
> 'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.

Darunter verstehe ich was anderes. Dass der Computer macht, was ich 
will. Wie das passiert, ist mir ziemlich egal, Hauptsache niemand kann 
mir vorschreiben, was ich machen kann, oder auch nicht. Daher ist mir da 
viel wichtiger, das mein Computer nicht ein abgeschottetes Smartphone 
oder was in die Richtung ist, und ich möglichst viel DRM zeug vermeide, 
als das alles in ASM geschrieben ist, bei dem keiner mehr durch blickt.
Gast #6873062
Lesenswert?

🐧 DPA 🐧 schrieb:

> Normalerweise bin ich ja kein fan von bitfields, aber
> bits reversen ist lästig. Da würde ich die dann doch
> nehmen, und das Optimieren dem Compiler überlassen:

Und Du glaubst, das wird schneller als
1
 
2
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;

(Es gibt auch eine Variante, die mit 32 Bit auskommt.)
Moderator Persönliche Seite #6873064
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:
> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen

Ich muss gar nix prüfen, der C-Code läuft einfach - auf dem einen µC 
performanter (dank rbit), auf dem anderen mangels passender Instruktion 
weniger performant. Aber was soll's?

Der Assembler-Programmierer muss den Code für jeden µC neu schreiben 
oder er verrottet auf seinem ATTiny. Bestes Beispiel: Moby, der kann 
auch nix anderes als ATTinys programmieren.
Gast #6873093
Lesenswert?

Assembler gehört zum Handwerkszeug schrieb:

> Also Programmierer steht man über die infantilen
> Streiteren ob assembler oder C der 'Heilige Scheiß' sei

Man folgert leicht: Du bist kein Programmierer.


> Und auch als Programmierer der den befehlssatz und
> CPU-Architekturen beherrscht,

Da hätte ich ja viel zu tun.

Wenn ich ein Anwendungsprogramm entwickle, will ich dem
Nutzer vor allem ein Werkzeug zur Verfügung stellen, das
sein Problem löst. Da ich nicht wissen kann, welche CPU der
Anwender benutzt, beschränke ich mich im wohlverstandenen
Eigeninteresse auf die Auswahl und die Optimierung von
Algorithmen, die mit üblichen Architekturen möglichst gut
harmonieren. Alles, was darüber ist, ist vom Übel.


> ist man nicht gezwungen alles in Assembler-Mnemonics zu
> schreiben, sondern kann ganz profesionell, inline Assembler
> verwenden, wo er gegenüber Compiler-hHrsteller spezifischen
> C-Konstrukten effizienter und schneller ist.

Frei nach C.F.Gauss: "Mangelnde computertechnische Bildung
zeigt sich am deutlichsten in äußerster Schärfe bei der
Mikro-Optimierung."


> Man will ja schliesslich 'Computer beherschen' und nicht als
> 'Syntax-idiotischer' C-Fachtrottel-Programmierschwein enden.

???

Ich will vor allem gute Programme schreiben.

Das ist etwas anderes als "Programme schreiben, die auf meinem
aktuellen Computer schnell laufen".
Gast #6873107
Lesenswert?

Frank M. schrieb:

> Assembler gehört zum Handwerkszeug schrieb:
>> Nein, es ist nicht mühelos jedesmal den Compiler zu überprüfen
>
> Ich muss gar nix prüfen, der C-Code läuft einfach - auf dem
> einen µC performanter (dank rbit), auf dem anderen mangels
> passender Instruktion weniger performant. Aber was soll's?

Naja, die Frage bleibt: Wie drücke ich das in C so aus, dass
der Compiler bei Verfügbarkeit "rbit" verwendet und andernfall
z.B. die von mir gepostete Formel?


> Der Assembler-Programmierer muss den Code für jeden µC neu
> schreiben

Dürfen nur Assemblerprogrammierer Assembleranweisungen
verwenden?
Gast #6873159
Lesenswert?

Egon D. schrieb:
> 🐧 DPA 🐧 schrieb:
>
>> Normalerweise bin ich ja kein fan von bitfields, aber
>> bits reversen ist lästig. Da würde ich die dann doch
>> nehmen, und das Optimieren dem Compiler überlassen:
>
> Und Du glaubst, das wird schneller als
> b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;

Ok, multiplizieren ist etwas schneller bei x86: 
https://godbolt.org/z/a1Ph37ffW

Aber auch wenn ich selbst Assembler geschrieben hätte wäre ich nicht auf 
die Idee gekommen.

Man könnte jetzt im build script ein benchmark einbauen, um eine 
Variante auszuwählen, oder alternativ je nach Architekturen in den build 
scripts hinterlegen, welche Variante besser ist. Aber das ist dann doch 
Overkill.
Gast #6873192
Lesenswert?

🐧 DPA 🐧 schrieb:

> Aber auch wenn ich selbst Assembler geschrieben hätte
> wäre ich nicht auf die Idee gekommen.

Bin ich auch nicht. Das stammt von den "bit twiddling hacks".


> Man könnte jetzt im build script ein benchmark einbauen,
> um eine Variante auszuwählen, oder alternativ je nach
> Architekturen in den build scripts hinterlegen, welche
> Variante besser ist. Aber das ist dann doch Overkill.

Warum eigentlich? Solche Grundoperationen können schon in
der bestmöglichen Variante zur Verfügung stehen, finde ich.
Man will ja das Rad nicht jedesmal neu erfinden...
Gast #6873477
Lesenswert?

🐧 DPA 🐧 schrieb:
> Aber auch wenn ich selbst Assembler geschrieben hätte wäre ich nicht auf
> die Idee gekommen.
>
> Man könnte jetzt im build script ein benchmark einbauen, ..

Man könnte beim Intel auch mal schauen, wie weit man hier mit LEA kommt. 
Oder mit den CPU-Erweiterungen. Die sind zwar oft mit Speicheraufruf 
verbunden, wie auch die FPU - aber  man kann auch Sachen machen, die der 
C oder ähnlich Compiler vermutlich eh nicht kann. Aber LEA geht schon 
mit Compiler. Ist aber auch alles ein wenig Übungsache.
Überhaupt ist man, wenn man so ein Forum mit Top-Leuten kennt, wenn es 
mal drauf ankommt, gar nicht so allein mit Fragen zum Code.

Vor allem auch deswegen, weil Assembler nur eine Möglichkeit ist, ein 
Programm schneller oder kleiner zu machen. Der wahre Hintergrund für 
bessere Programme ist aber Know How und Hingabe, nicht irgendeine 
Programmierhilfe.

Früher war der Gedanke verbreitet, der Computer macht die Musik. Das ist 
aber nur ein Irrglaube, eine Täuschung.
#6873545
Lesenswert?

Egon D. schrieb:
>> Man könnte jetzt im build script ein benchmark einbauen,
>> um eine Variante auszuwählen, oder alternativ je nach
>> Architekturen in den build scripts hinterlegen, welche
>> Variante besser ist. Aber das ist dann doch Overkill.
>
> Warum eigentlich? Solche Grundoperationen können schon in
> der bestmöglichen Variante zur Verfügung stehen, finde ich.
> Man will ja das Rad nicht jedesmal neu erfinden...

Die diversen build tools (make, cmake, automake, meson) haben das noch 
nicht fertig eingebaut. Es gibt Wege, das dort selbst einzubauen, aber 
das ist aufwändig, und die meisten Entwickler wollen sich nicht all zu 
sehr mit den Buid Tools herumschlagen.

Ich habe als Beispiel in make mal etwas herum experimentiert, wie so 
etwas aussehen könnte: 
https://github.com/Daniel-Abrecht/test-variouse-make-stuff

Es ist bei weitem nicht perfekt, einiges fehlt noch, aber gibt eine 
grobe Idee, was man so alles machen könnte.
(Firma: S-C-I DATA GbR) #6875775
Lesenswert?

Mal noch eine Frage um da nochmals Nachzuhaken.
Welchen CPU verwendest du überhabt?

Ich habe grad heute in einer Software genau das Bit-spiegeln 
gebraucht(war für eine Tastatur-abfrage).

Glücklicherweise habe ich einen µP Verwendet der ein "LEA" Coprozessor 
onboard hat, der ist speziell für Filter,DSP, FFT Funktionen.
Da gibt es doch tatsächlich ein befehl für genau dies mit 8/16 oder 32 
Bit macht.
1
msp_cmplx_bitrev_q15    Complex bit-reversal function
2
msp_cmplx_bitrev_iq31   Complex bit-reversal function
(Firma: S-C-I DATA GbR) #6875811
Lesenswert?

Computer-Spezialist schrieb:
> Also für die meisten nicht.
> Für einige offenbar schon.

Problem ist es nicht, aber wenn ich dass als Programm schreibe erkennt 
der IAR C Kompiler dies nicht selbstständig, dass man ja den LEA-Core 
dazu "missbrauchen" kann und "Bastelt" eine Ruine die sage und schreibe 
65 Cycles braucht, das hat mich genervt und an den Thread hier gedacht.
Habe dann einfach die Daten ans richtige LEA Register übergeben und kann 
das Reversebyte dann abholen. braucht noch 6 Cyclen für 16 Bit!

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