Frage

Ich mache eine Vektor / Matrix-Bibliothek. (GCC, ARM NEON, iPhone)

typedef struct{ float v[4]; } Vector;
typedef struct{ Vector v[4]; } Matrix;

Ich ging struct Daten als Zeiger zu vermeiden Leistung degradiert von Daten zu kopieren, wenn die Funktion aufgerufen wird. Also ich Funktion ausgelegt, wie dies auf den ersten:

void makeTranslation(const Vector* factor, Matrix* restrict result);

Aber, wenn die Funktion inline ist, gibt es keinen Grund für die Leistungswerte als Zeiger zu übergeben? Sie diese Variablen werden ebenfalls kopiert? Wie wäre es Register und Caches? Ich habe versucht, Funktion wie folgt neu zu gestalten:

inline Matrix makeTranslation(const Vector factor) __attribute__ ((always_inline));

Wie denken Sie über die Kosten der einzelnen Fälle nennen?

  • Ich habe 'const' bis 2. Signatur Vorschläge zu reflektieren.
War es hilfreich?

Lösung

Wenn die Funktion inline ist in der Regel nicht das Kopieren von Variablen direkt mit dem Anruf beteiligt. Variablen werden manchmal noch als normaler Teil der Ausführung auf dem Stapel bewegt sich um und gesetzt werden, aber nicht als direkte Folge des Funktionsaufrufs. (Wenn Sie von Registern ausgehen, bekommen einige Werte auf den Stapel gelegt können, etc ... aber nur, wenn nötig.) So der Overhead der „Ruf“ verschwindet im Grunde, wenn eine Funktion inlined (nicht mehr Einrichtung / Abbauen der Stapelrahmen, nicht mehr unbedingter Sprung, nicht mehr Schiebe- / poping Parameter.)

Wenn Sie auf Ihrem always_inline Attribut verlassen, um immer Inline die Funktion, dann sollten Sie auch den Vektor nicht durch Zeiger übergeben (wenn es nicht geändert wird). Der Grund dafür ist, dass es durch den Zeiger Passieren des Vektors erfordert Adresse genommen werden, was bedeutet, dass der Compiler muss sicherstellen, dass er eine Adresse hat und somit kann es nicht nur in CPU-Registern vorhanden ist. Dies kann Dinge verlangsamen, wenn es nicht benötigt wird, und wenn Sie die Adresse von etwas der Compiler nehmen immer sicherzustellen, dass es eine Adresse hat, da der Compiler nicht sicher, dass die Adresse sein, kann nicht erforderlich.

Aufgrund der Pass-by-Zeiger, wird dieser Code immer eine Anweisung hat die Objektadresse zu erhalten, und mindestens ein dereferenzieren an einem Mitglied Wert zu erhalten. Wenn Sie Pass-by-Wert dann kann dies immer noch passieren, aber der Compiler kann in der Lage sein, sich all das zu optimieren.

nicht vergessen, dass übermäßiger Einsatz von inlining kann die Größe des Compilers Binärcode deutlich erhöhen. In bestimmten Fällen große Codesegmente (als Folge der Inline-Funktionen) kann mehr Befehls-Cache-Misses verursacht mit einer schlechteren Leistung führen wird, da die CPU ständig in dem Hauptspeicher zu gehen, ist mit Teilen des Programms zu holen, weil ein Teil davon ist zu groß in der kleinen L1-Cache zu passen. Dies kann in Embedded-Prozessoren besonders wichtig sein (wie das iPhone), da diese Prozessoren typischerweise kleine Caches haben.

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