Ist es überhaupt sinnvoll für einen Compiler machen eine Struktur wie diese in einem CPU-Register an eine Funktion zu übergeben?

StackOverflow https://stackoverflow.com/questions/4213107

Frage

Ich würde gerne wissen, ob irgendeine Art von Struktur enthält mehr als eine primitive, aber seine Gesamtgröße ist kleiner oder gleich der Größe eines einzelnen CPU-Register wie ein 4-Byte-Register, ist es immer sinnvoll, einen Compiler machen es in einer dieser 4-Byte-Register zu setzen, wenn sie von Wert oder Bezug auf eine Funktion, anstelle der Herstellung einer Kopie davon auf den Angerufenen Stapel oder Hindurchleiten eines Zeiger darauf und im allgemeinen vorbei, wenn etwas mehr als eine einzige primitive Passieren eine Funktion wie ein Array oder eine Struktur würde in einem CPU vorbei jemals praktisch Register kommen?

Beispiel einer solchen Struktur:

struct sample{
 public:
  char char1;
  char char2;
};

Probe von der Struktur an eine Funktion:

void someFunc(const sample input){
 //whatever
}
void someFunc(sample input){
 //whatever
}
void someFunc(sample & input){
 //whatever
}
void someFunc(const sample & input){
 //whatever
}
War es hilfreich?

Lösung

Ja. Viele Compiler haben ein spezielles Schlüsselwort oder type-Attribut, dass Sie, dass eine Struktur festlegen können, sollte in Registern übergeben werden, anstatt auf dem Stapel. Es ist häufiger auf Prozessoren, die viele Register und tiefe Pipelines, wie die PowerPC haben und kann eine enorme Leistungssteigerung in Architekturen, in denen einen Wert in dem Speicher zu schreiben und sie dann wieder sofort zu lesen verursacht einen Pipeline-Stall.

In der Regel würden Sie nur für eine Struktur verwenden es, die die gleiche Größe wie eine native Register ist. Insbesondere ist es sinnvoll, auf Prozessoren, die breiten SIMD-Register haben, die 16 Bytes zu einer Zeit oder mehr passieren können. Das würde Sie (zum Beispiel) einen 4-dimensionalen Vektor (vier Schwimmer) auf einem Register übergeben. AMDs System V ist ein Beispiel für ein x86-ABI, die dies ermöglicht.

Ein anderes Beispiel ist d64_abi type-Attribut des GCC, die einen PowerPC erzählt eine Struktur auf Register passieren, wo möglich, anstatt auf dem Stapel. (Dies ist Teil der Darwin ABI ).

typedef struct {
    int          a;
    float        f;
    char         c;
} __attribute__ ((d64_abi)) Thingy;

Thingy foo( Thingy t );

Im obigen Fall ein Aufruf Foo würde die Thingy auf einem Float-Register und zwei int-Registern übergeben, anstatt es in den Stack zu schreiben und es gleich wieder zu lesen. Der Rückgabewert kommt auf Register in der gleichen Art und Weise zurück.

Ich habe noch nie einen Compiler gesehen, dass dies automatisch tut, ohne es zu sagen, aber es ist möglich, ein solches vorhanden ist.

Andere Tipps

Dies ist in der Application Binary Interface (ABI) Ihrer Ausführungsumgebung definiert. Der Standard sagt nichts über Prozessor-Register, wenn eine Funktion aufgerufen wird, so dass es legal ist, eine Umgebung zu schaffen, in dem kleine Strukturen in einem einzigen Prozessorregister gepackt sind.

Für das Referenzteil sind sie sehr wahrscheinlich ohnehin vergangen als Zeiger werden, da, wenn sie innerhalb der aufgerufenen Funktion der Adresse einer Referenz genommen wird, an die Adresse des referenzierten Objekts lösen muß.

Auf bestimmten Architekturen (wie i386, ich weiß, es ist alt, aber das ist, was ich mit aufwuchs;) es ist sicherlich sinnvoll, es zu passieren in einem Register, da drängen und aus dem Stapel knallen mehr viel nehmen (etwa zwischen 3 -6-mal mehr) CPU-Zyklen, wie durch das Register übergeben. So ein Compiler, einen guten Job zu optimieren für das tun würde.

Ich kann mir vorstellen es gibt auch andere Architekturen, bei denen es keine Rolle spielt. Oder wenn die Register im Einsatz für andere Optimierungen sind, die eine weitere Verbesserung ergeben, macht es keinen Sinn machen sie für diese zu verwenden.

Was Architektur verwenden Sie / Targeting, oder fragen Sie im Allgemeinen?

Ich denke, es ist Compiler, die PODs in Registern übergeben werden, auch wenn sie structs sind.

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