Was ist der schnellste Weg, um die Bits in einem 8x8 Block auf Bits zu drehen?

8

Ich bin mir nicht sicher, was genau ich genau sagen soll. Ich habe einen 8x8 Block von bits in 8 bytes gespeichert, jedes Byte speichert eine Zeile. Wenn ich fertig bin, möchte ich, dass jedes Byte eine Spalte speichert.

Zum Beispiel, wenn ich fertig bin:

%Vor%

Was ist der einfachste Weg dies in C zu tun, der gut funktioniert?

    
Roland Rabien 03.08.2011, 17:34
quelle

6 Antworten

15

Dieser Code wird direkt von " Hacker's Delight "- Abbildung 7-2 Transponieren einer 8x8-Bit-Matrix nehme ich nicht an es:

%Vor%

Ich habe nicht überprüft, ob sich das in die Richtung dreht, die Sie benötigen, andernfalls müssen Sie möglicherweise den Code anpassen.

Beachten Sie auch die Datentypen & amp; Größen - int & amp; unsigned (int) sind möglicherweise nicht 32 Bit auf Ihrer Plattform.

Übrigens, ich vermute, dass das Buch (Hacker's Delight) für die Art von Arbeit, die Sie machen, essentiell ist ... schaut es euch an, viele tolle Sachen drin.

    
Dan 03.08.2011, 19:44
quelle
5

Wenn Sie nach der einfachsten Lösung suchen:

%Vor%

Wenn Sie nach der schnellsten Lösung suchen:

So transponieren Sie eine Bitmatrix in der Montage mit SSE2.

    
Andrejs Cainikovs 03.08.2011 17:51
quelle
3

Lisp-Prototyp:

%Vor%

So können Sie den Code ausführen:

%Vor%

Gelegentlich zerlege ich den Code, um sicherzustellen, dass keine unnötigen Aufrufe von Sicherheitsfunktionen erfolgen.

%Vor%

Dies ist ein Benchmark. Führen Sie die Funktion oft genug aus, um ein (binäres) HDTV-Bild zu verarbeiten.

%Vor%

Das dauerte nur 51ms. Beachten Sie, dass ich ziemlich viel zähle, weil die Funktion die ganze Zeit neue 8-Byte-Arrays zuweist. Ich bin mir sicher, dass eine Implementierung in C viel mehr optimiert werden kann.

%Vor%

Hier sind einige weitere Testfälle:

%Vor%

Jetzt möchte ich wirklich sehen, wie mein Code mit Andrejs Cainikovs C Lösung verglichen wird ( Bearbeiten: Ich denke, es ist falsch ):

%Vor%

Und Benchmarking:

%Vor%

Jede Schleife über das HDTV-Bild dauert 2,5 ms. Das ist viel schneller als mein nicht optimierter Lisp.

Leider liefert der C-Code nicht die gleichen Ergebnisse wie mein Lisp:

%Vor%     
whoplisp 03.08.2011 17:44
quelle
2

Das klingt sehr nach einer sogenannten "Chunky to Planar" -Routine, die auf Displays verwendet wird, die Bitplanes verwenden. Der folgende Link verwendet MC68K Assembler für seinen Code, bietet aber einen schönen Überblick über das Problem (vorausgesetzt, ich habe die Frage richtig verstanden):

Ссылка

    
user786653 03.08.2011 17:39
quelle
1

Sie möchten wirklich etwas mit SIMD-Befehlen mit etwas wie der GCC-Vektorvektor-Unterstützung machen: Ссылка

    
gby 03.08.2011 17:40
quelle
1

Wenn Sie eine optimierte Lösung wollten, würden Sie die SSE-Erweiterungen in x86 verwenden. Sie müssten 4 dieser SIMD-Opcodes verwenden. MOVQ - 8 Bytes verschieben PSLLW - gepackte Verschiebung der linken logischen Wörter PMOVMSKB - gepacktes Verschiebungsmaskenbyte Und 2 normale x86 Opcodes LEA - effektive Adresse laden MOV - Verschieben

%Vor%

25 x86 Opcodes / Anweisungen im Gegensatz zu der gestapelten for ... Loop-Lösung mit 64 Iterationen. Entschuldigung, die Notation ist nicht die ATT-Stilsyntax, die c / c ++ - Compiler akzeptieren.

    
LastCoder 03.08.2011 19:21
quelle