Frage

Hier ist eine Funktion, dass ich auf 64-Bit-Linux-Maschine schreibe.

void myfunc(unsigned char* arr) //array of 8 bytes is passed by reference
{
   unsigned long a = 0; //8 bytes
   unsigned char* LL = (unsigned char*) &a;

   LL[0] = arr[6];
   LL[1] = arr[3];
   LL[2] = arr[1];
   LL[3] = arr[7];
   LL[4] = arr[5];
   LL[5] = arr[4];
   LL[6] = arr[0];
   LL[7] = arr[2];
}

Nun meine Fragen sind:

  1. Will Variable 'a' in einem Register gespeichert werden, so dass es wieder zugegriffen werden würde nicht wieder aus dem RAM oder chache?
  2. Arbeiten auf 64-Bit-Architektur, sollte Ich gehe davon aus, dass 'arr' Array wird in einem Register gespeichert wird als Funktionen Parameter in einem Register in 64-Bit-Bogen gespeichert werden?
  3. Wie effizient ist Zeigerart Gießen? meine Vermutung ist, dass es überhaupt ineffizient sein sollte?

Jede Hilfe wäre appriciated werden.

Viele Grüße

War es hilfreich?

Lösung

  1. a kann nicht in einem Register gespeichert werden, da Sie die Adresse genommen haben. (Valdo richtig weist darauf hin, dass ein wirklich intelligenten Compiler könnte optimize das Array greift in Bit-Operationen und verlassen a in einem Register, aber ich habe noch nie ein Compiler tun, und ich bin nicht sicher, dass es gesehen aufzuwickeln würde schneller ist).
  2. arr (der Zeiger selbst) in einem Register gespeichert (%edi, auf amd64). Die Inhalt des Arrays ist im Speicher.
  3. Pointer type casting von selbst erzeugt oft keinen Code überhaupt. führen zu tun dumme Sachen mit Typ-Casts kann jedoch sehr ineffizient Code oder sogar Code, dessen Verhalten ist nicht definiert.

Es sieht aus wie Sie versuchen, die Bytes in einem Array permutieren und dann schieben in eine Reihe, und der Maschinencode Ihr Beispiel ist für das nicht furchtbar schlecht erzeugt. David Vorschlag zur Verwendung Verschiebung und Maske Operationen stattdessen ist gut (dies wird auch Probleme vermeiden, wenn Ihr Code jemals auf einer Big-Endian-Maschine ausgeführt werden muss), und es gibt auch die SSE-Vektor permute Anweisungen, aber ich habe sie sind irgendwie gehört ein Schmerz zu verwenden.

Im übrigen sollten Sie den Rückgabetyp Ihrer Beispielfunktion machen ganz am Ende unsigned long und Put-return a; sein; dann können Sie gcc -O2 -S und genau sehen, verwenden, was Sie von der Kompilierung bekommen. Ohne die Änderung Rückkehr a, GCC wird fröhlich optimize weg der ganze Körper der Funktion, da es keine äußerlich sichtbare Nebenwirkungen.

Andere Tipps

Sie könnten es besser machen explizite Verschiebung zu verwenden und Anweisungen zu maskieren dies zu erreichen, anstatt Array-Indizierung zu verwenden.

Die Array-Operationen machen wollen schwieriger für den Compiler für diese Register zu verwenden, da es in der Regel keine Anweisungen, die Dinge wie „Last 8 Bits aus dem dritten Byte des Registers A“ zu tun. (Eine Optimierung der Compiler könnte Figur heraus, dass es möglich ist, dies zu tun mit Verschiebungen / Masken, aber ich bin nicht sicher, wie wahrscheinlich das ist).

  1. Die Frage nach, ob die Variable a wird in dem Register gespeichert wird, ist eine Frage der Optimierung. Da es kein volatile ist Modifikator einen intelligenten Compiler IMHO wird dies tun.

  2. Es ist eine Frage der Aufrufkonvention. Wenn vereinbarungsgemäß ein einzelner Zeigerparameter in einem Register übertragen wird, -. Wird so sein arr

  3. Gusszeigertyp ist nicht eine Operation, die CPU interpretiert. Es gibt keinen Code dafür generiert. Es ist einfach die Informationen für den Compiler über das, was meinst du.

(Eigentlich manchmal Gießen produzieren zusätzlichen Code, aber dies ist auf mehrere Vererbung und Polymorphismus im Zusammenhang)

Abhängig von Ihrer Optimierungsstufe. Sie können die Baugruppe prüfen, Ihre Fragen zu beantworten. Mit gcc, verwenden Sie die "-S" -Kennzeichen.

gcc -S -O0 -o /tmp/xx-O0.s /tmp/xx.c
gcc -S -O3 -o /tmp/xx-O3.s /tmp/xx.c

Die erzeugte Baugruppe ist vollständig anders. (Achten Sie darauf, die return a; Änderung von Zack vorgeschlagen zu machen.)

Siehe auch Diese Nachricht für Hinweise, wie man erzeugen eine gemischte c / Montage Auflistung (die schnell nutzlos mit Optimierung wird).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top