Lesen in den Speicher von PIC32MX in C und XORing großer Datensätze

Ich habe ein Projekt, in dem ich 102 8-Bit-PISO-Schieberegister in Daisy-Chain-Konfiguration habe und sie an eine gemeinsame SDI-Leitung ausgeben, die mit einem PIC32MX-Controller verbunden ist.

Es gibt insgesamt 816 Bits, die ich lesen und im Speicher speichern muss, damit ich die gelesenen Daten manipulieren kann. Außerdem muss ich sie 34 Mal lesen, da die Anwendung erfordert, dass ich diese 816 Bits für jede dieser Leseoperationen XOR-verknüpfe.

Ich habe zwei Fragen:

  • Wie würden Sie die Daten speichern? Ich mache mir Sorgen, weil ich ziemlich viele Daten verarbeiten muss und ich versuche, die Verarbeitung auf ein Minimum zu optimieren. Beachten Sie, dass ich in der Lage sein muss, die (Zeilen-, Spalten-) Indizes zu extrahieren, damit ich andere Werte entsprechend berechnen kann.
  • Nachdem ich die Daten XOR-verknüpft habe, muss ich die Struktur durchlaufen und Vorkommen von Nullen finden. Was schlagen Sie in Bezug auf den Suchalgorithmus vor?

Ich habe darüber nachgedacht, eine Matrix mit der Dimension [34.816] zu erstellen und die Zeilen nacheinander mit XOR zu einem einzelnen Array mit 816 Spalten zu verknüpfen und dann nach Nullen im Array zu suchen, aber ich bin mir nicht sicher, wie ich das machen soll, irgendwelche Gedanken?

Sie haben also 102 CS-Zeilen? Das klingt eher nach einem allgemeinen Programmierproblem, das nichts mit elektronischem Design zu tun hat. Ich empfehle, es nach stackoverflow.com zu verschieben , wo Sie möglicherweise bessere Ratschläge zu Algorithmen erhalten.
@tcrosley, ich stimme eher zu, obwohl ich mich aufgrund der Auswirkungen der Programmierung in einer PIC-Architektur entschlossen habe, es hier zu posten. Wie könnte ich die Frage dorthin verschieben?
Alle Schieberegister geben Bit für Bit an dieselbe Leitung aus. Welches Schieberegister gerade aktiv ist, wähle ich mit Johnson-Zählern aus. Ich werde nur von einem Pin lesen, aber das ist nicht mein Problem, die Speicherverwaltung und der Suchalgorithmus sind ... :)
Ich war nur neugierig auf die CS. Ich habe dies zur Aufmerksamkeit des Moderators gemeldet.
Ich denke, diese Frage ist eng genug mit der eingebetteten Programmierung verbunden, dass sie vorerst hier bleiben sollte.

Antworten (1)

Um die Bits so effizient wie möglich zu verarbeiten, sollten Sie sie, wo immer es sinnvoll ist, in 32-Bit-Wörter packen. 816 Bit sind 25,5 Wörter, was wirklich nicht schlecht ist.

Um effizient nach Einsen zu suchen, unterteilen Sie die Aufgabe in zwei Schritte: Überprüfen Sie in der äußeren Schleife ganze Wörter auf Nicht-Null und suchen Sie dann in der inneren Schleife nach einzelnen Bits in den Wörtern, die nicht alle Null sind.

Ein Trick, der verwendet werden kann, um einzelne Bits in einem Wort mit mehreren gesetzten Bits zu isolieren, besteht darin, das Wort mit seiner Negation (2er-Komplement) UND zu verknüpfen. Das Ergebnis hat nur ein einziges gesetztes Bit – die „Eins“ ganz rechts im ursprünglichen Wort. Sie können dieses Ergebnis dann verwenden, um dieses Bit zu löschen und nach der nächsten „Eins“ zu suchen.

In C:

temp = word & -word;
word &= ~temp;

Angenommen, Ihr 32-Bit-Wort enthält 0x40010080:

01000000000000010000000010000000  original word
10111111111111101111111110000000  ... negated
00000000000000000000000010000000  ... and then ANDed together

11111111111111111111111101111111  complement of previous word
01000000000000010000000000000000  ... ANDed with original word for next iteration

BEARBEITEN:

Die Effizienz dieses Algorithmus ergibt sich aus der Tatsache, dass Sie nur einmal für jede „Eins“ (drei davon in diesem Beispiel) iterieren und nicht einmal für jedes der 32 Bits im Wort. Dies ist ein großer Vorteil, wenn Sie so etwas wie das einfache Zählen der Einsen tun. Der Nachteil ist, dass Sie den Bit-Index nicht direkt erhalten, aber es gibt auch Möglichkeiten, dies zu beschleunigen. Um beispielsweise den Bitindex eines einzelnen Bitsatzes in einem Wort zu erhalten, könnten Sie einen binären Codierungsalgorithmus verwenden:

index = 0;
if (word & 0xAAAAAAAA) index += 1;
if (word & 0xCCCCCCCC) index += 2;
if (word & 0xF0F0F0F0) index += 4;
if (word & 0xFF00FF00) index += 8;
if (word & 0xFFFF0000) index += 16;

Der Gesamtvorteil der beiden obigen Algorithmen im Vergleich zu einer Brute-Force-Iteration durch die Bits hängt davon ab, wie viele Bits Sie in jedem Wort erwarten. Wenn sie selten sind (weniger als etwa 4 pro Wort), sollten diese Algorithmen schneller sein. Wenn sie häufiger vorkommen, verwenden Sie einfach die iterative Schleife:

for (index = 0, mask = 0x00000001; index < 32; ++index, mask <<= 1) {
  if (word & mask) {
    /* do your processng here */
  }
}
Es tut mir leid, aber ich konnte Ihnen in Bezug auf Ihren letzten Absatz nicht folgen (kein englischer Muttersprachler). Können Sie das näher erläutern?
Danke für ihre schnelle Antwort! Ich habe jetzt verstanden, was Sie meinten, aber ich verstehe immer noch nicht, wie dies die Effizienz erhöht. Brauche ich diese Operation wirklich? Ich dachte daran, den Index (bis zu 816) einfach zu berechnen, wenn der Wert eines bestimmten 32-Bit-Wortes größer als 0 wäre - denken Sie nicht, dass es schneller ist?
Außerdem meinte ich, 0 zu finden, nicht 1.
Um Nullen zu finden, können Sie diesen Algorithmus immer noch verwenden, invertieren Sie einfach zuerst die Daten (oder, wenn die Daten, mit denen Sie XORen, fest sind, invertieren Sie einfach diese ). Die Effizienz dieses Algorithmus ergibt sich aus der Tatsache, dass Sie nur einmal für jede „Eins“ (drei davon in diesem Beispiel) iterieren und nicht einmal für jedes der 32 Bits im Wort. Dies ist ein großer Vorteil, wenn Sie so etwas wie das einfache Zählen der Einsen tun. Der Nachteil ist, dass Sie den Bitindex nicht direkt erhalten, aber es gibt auch Möglichkeiten, dies zu beschleunigen. Programmierst du in C oder Assembler?
Nochmals vielen Dank für Ihre Hilfe! Ich werde in C programmieren. Können Sie bitte einen Einblick geben, wie Sie einen solchen Algorithmus implementieren würden?
Siehe meine Bearbeitung oben.
Sir, ich fühle mich von Ihren Lehren gedemütigt! Viele Grüße! :)