Ich habe eine 64 Bit Binärzahl, in der steht leider das niederwertigste Bit links, das höchstwertige rechts.
Bevor ich jetzt anfange, jedes Bit einzeln umzusortieren, frage ich erstmal:
Gibt es eine einfache (mathematische) Möglichkeit, die ganze Zahl um 180° zu drehen?
In Assembler würde ich es aus einem Register z.B. links herausschieben und über das Carryflag in ein anderes Register links reinschieben.
Für 64 Bit sind das allerdings 16 Register, in einem 8-Bitter wie dem AVR ist damit schon die Hälfte aller Register belegt.
Na dann ist es doch einfach, weil
"MMBasic allows the embedding of compiled C programs for high performance functions"
Also einfach den vorgeschlagenen ARM-maschinenbefehl ("RBIT") als online in C einbinden, kompilieren und dem Basic vor die Füße werfen. Ferdsch!
Beitrag "Re: Zahl umdrehen?"
Wobei, der RP2040 als CortexMo doch 32bit lange Register hat?!
Interessanterweise gibt es im GCC zwar Builtins um Bytes, Halbworte etc umzudrehen, nicht aber bei Bits. Genau das wäre aber die sinnvollste Stelle, weil viele Architekturen entsprechenden Hardware-Support haben.
Einfach mit einer Lookup-Table arbeiten. Passt genau in 131072 PiByte
Wenn man eine Lookup-Tabelle für 8 Bit-Zahlen erstellt, belegt diese ganze 256 Bytes. Soviel Platz im ROM sollte sein. Dann kann man die 64bit-Zahl in 8 Schritten à 1 Byte umdrehen. Das ginge deutlich schneller als die 64Bits einzeln zu schieben.
Einfach mit einer Lookup-Table arbeiten. Passt genau in 131072 PiByte
Wenn man eine Lookup-Tabelle für 8 Bit-Zahlen erstellt, belegt diese
ganze 256 Bytes. Soviel Platz im ROM sollte sein. Dann kann man die
64bit-Zahl in 8 Schritten à 1 Byte umdrehen. Das ginge deutlich
schneller als die 64Bits einzeln zu schieben.
Ja, wenns ums Platzsparen geht, dann wird man mit einer 1bit LUT noch viel mehr sparen koennen...
Bevor ich jetzt anfange, jedes Bit einzeln umzusortieren, frage ich
erstmal:
Naja. Die Frage ist schlicht, wie schnell es denn WIRKLICH sein muss? Du musst sicher NICHT die Zahl in 1us umdrehen und auch nicht 1M davon.
Wenn der triviale Ansatz der Bitschieberei schnell genug ist, nimm ihn und wende dich den wirklich wichtigen und interessanten Aufgaben deines Projektes zu.
Welchen? 32Bit oder 64Bit? Und wo finde ich auf github irgendwelche
Diskussionsforen?
github: MicroPython: Discussions
Hab' erst eine recht schnelle Python-Viper Routine geschrieben, danach eine Python-Thumb-Assembler Version und dann den schnellsten Vorschlag mit PIO Assembler und DMA gemacht. Der war - wie du schon geschrieben hattest - so trivial, das ihn nur erwähnt hatte.
War zwar nur 32bit, aber sinngemäß geht's natürlich mit beliebigen Bitweiten.
War zwar nur 32bit, aber sinngemäß geht's natürlich mit beliebigen
Bitweiten.
Ähem, nö. Mit den einfachen PIO-Programmen ist bei diesem konkreten Problem bei 96 Bit Schicht im Schacht. Liegt daran, dass die PIO halt nur vier Register hat, davon nur zwei "frei verwendbare" (hier natürlich als Cache für das Reverse der Long-Words).
128Bit oder gar 256Bit mit vMax zu reversen braucht eine Kombination aus PIO und ARM-Assembler.
Bei max. 2048b:
Eine PIO-SM hat jeweils vier ›WORD‹ FIFO kann also 8*32b = 256b ohne weiteres halten. Vier davon sofort verarbeiten und vier im FIFO halten. Acht SM können so 2048b entgegen nehmen.
Die Daten müssen ja sowieso irgendwo stehen, bevorzugt in einem array.
Man kann 64 ›WORD‹ aus dem array lesen und ungebremst in die PIO-FIFOs schieben. Dann liest man ungebremst 64 ›WORD‹ und schreibt sie rückwärts in das array zurück.
Wenn größer 2048b, dann kann man auch noch den Stapel nutzen. Wenn der nicht reicht, wird's akademisch… ;-)
Eine PIO-SM hat jeweils vier ›WORD‹ FIFO kann also 8*32b = 256b ohne
weiteres halten. Vier davon sofort verarbeiten und vier im FIFO halten.
Die FIFOs sind aber leider aus der PIO heraus nicht wahlfrei zugänglich. Deswegen heißen die Befehle für den Zugriff darauf auch PUSH/POP. Sprich: die "Drehung" der Daten auf der Ebene von 32Bit-Wörtern ist nur über Zwischenspeicherung in der PIO möglich. Deswegen ist deren Registerzahl hier der limitierende Faktor.
Die Daten müssen ja sowieso irgendwo stehen, bevorzugt in einem array.
Die PIO kann eben nicht wahlfrei darauf zugreifen, sondern nur als FIFO. Also nix mit Array.
Acht SM können so 2048b entgegen nehmen.
Ja klar, mit mehr PIO-Instanzen geht natürlich mehr als mit nur einer.
Die FIFOs sind aber leider aus der PIO heraus nicht wahlfrei zugänglich.
Wenn du Zahlen größer ›WORD‹ (sagen wir mal 8*32bit) in einem Speicherbereich liegen hast, dann müssen die sowieso in 32bit Stücken in den FIFO geschoben werden. Geht nicht anders.
Bei einem zu spiegelnden 256bit Wert kann man mit einem
›mov‹ index 0
und acht
›ldr‹ RAM[index]
›add‹ index 1
›str‹ TX_FIFO
Befehlssequenzen ohne zu warten in den (Eingangs-)FIFO schreiben. Die ersten vier Werte holt sich das PIO-Programm direkt ab, reversiert und schreibt sie in den (Ausgangs-)FIFO. Der ›stalled‹ dann, weil voll. Die letzen vier Werte stehen jetzt noch im (Eingangs-)FIFO. Alles ist randvoll.
Jetzt müssen die Werte gelesen werden und zurück in's RAM. Also wieder:
›mov‹ index 0
Acht mal
›ldr‹ RX_FIFO
›add‹ index 1
›str‹ RAM[index]
Sobald ein Wert aus dem RX_FIFO gelesen wird, rutscht den nächste automatisch aus dem TX_FIFO, wird gespiegelt und in den RX_FIFO geschoben.
Damit sind schließlich die acht ›WORD‹ sowohl gespiegelt als auch (im RAM) vertauscht.
Da braucht man noch nicht mal X und Y, ISR und OSR reichen aus.
Und nur einen einzigen PIO-Assembler Befehl.
Dem aufmerksamen Beobachter wird nicht entgangen sein, das die ›add‹ und ›str‹ Befehle im zweiten Teil getauscht werden müssen. Verfluchtes copy'n'paste. ;-)
Leider kann man bei der momentanen Boardsoftware Beiträge nicht sinnvoll ändern.
Peter hatte bereits einige Male Fragen zu Picomite Basic gestellt. Es darf mit einiger Wahrscheinlichkeit angenommen werden, das ein Pi Pico mit RP2040 (also ARM Cortex-M0plus) zum Einsatz kommt.
Und vermutlich noch nicht mal das Handbuch der CPU gelesen.
Naja, er dachte wohl, es gib irgendeinen mathematischen Trick.
Tatsächlich beziehen sich 180 Grad eher auf eine Kreisvorstellung. Wenn man das auf eine Uhr anwendet, braucht man praktisch nur die 12 nach unten ziehen.
Wenn man 64 Bit kreisförmig anordnet, kann man das auch machen - per Rotation. In diesem Fall in 32 Schritten.
Da wäre dann aber nur der obere Teil mit dem unteren vertauscht.
Möglicherweise nicht das gesuchte Ergebnis
Ganz abgesehen davon, dass das nicht die schnellste Methode wäre (s.o.).
Gestern hatte ich noch zwei Links gefunden, die nur die Grundlagen bearbeiten, und deswegen hatte ich mir die erspart. Aber nach den vielen guten Hinweisen oben ist mir das jetzt auch egal ;)
Es
darf mit einiger Wahrscheinlichkeit angenommen werden, das ein Pi Pico
mit RP2040 (also ARM Cortex-M0plus) zum Einsatz kommt.
Genau so ist es.
Aber ich wollte allgemeine und einfache Antworten, die ich in PicoMite umsetzten kann, deshalb keine näheren Angaben. Mit den Kernen des RP2040 kann ich (noch lange) nichts anfangen...
Ich habe das Problem auf die unelegante Weise gelöst:
Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen zweiten String kopiert.
Ich habe das Problem auf die unelegante Weise gelöst:
Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen
zweiten String kopiert.
Und warum dann nicht noch komplizierter?
Du weisst doch, daß nix langsamer ist, als hantieren mit Strings?
Und 64 Mal ein integer schieben ist immer noch um ein vielfacher schneller.
1
#include<stdio.h>
2
#include<stdint.h>
3
4
uint64_tDreheBitsUm(uint64_tzahl){
5
uint64_tumgedreht=0;
6
uint64_tnn=zahl;
7
for(;nn;nn>>=1){
8
umgedreht<<=1;
9
umgedreht+=(nn&1);
10
}
11
returnumgedreht;
12
}
13
14
intmain(){
15
uint64_txx;
16
xx=DreheBitsUm(0xdeadbeef);
17
printf("Umgedreht = 0x%X",xx);
18
return0;
19
}
Und dann vergleiche mal um wieviel schneller das ist...
Ich habe das Problem auf die unelegante Weise gelöst:
Zahl in String umgewandelt und Zeichen für Zeichen umgekehrt in einen
zweiten String kopiert.
Und warum dann nicht noch komplizierter?
Daß es beim TO um PicoMite geht, sollte mittlerweile jedem klar sein. Dann gib ihm bitte auch ein Beispiel in BASIC, damit er etwas damit anfangen kann.
Daß irgendetwas ganz schnell gehen müßte, war nicht die Frage. Nur steigert man sich hier gerne dahin, daß maximal ein CPU-Takt zulässig sei.