Wie kann man Funktionsrückgabewerte in C und C ++ auf x86-64 optimieren?
Das x86-64 ABI gibt zwei Rückgaberegister an:rax
undrdx
, beide 64-Bit (8 Byte) groß.
Angenommen, x86-64 ist die einzige Plattform, auf die abgezielt wird, und welche dieser beiden Funktionen:
uint64_t f(uint64_t * const secondReturnValue) {
/* Calculate a and b. */
*secondReturnValue = b;
return a;
}
std::pair<uint64_t, uint64_t> g() {
/* Calculate a and b, same as in f() above. */
return { a, b };
}
würde angesichts des aktuellen Status von C / C ++ - Compilern, die auf x86-64 abzielen, eine bessere Leistung erzielen? Gibt es leistungsbezogene Probleme bei der Verwendung der einen oder anderen Version? Können Compiler (GCC, Clang) das @ immer optimierestd::pair
wird in @ zurückgegebrax
undrdx
?
AKTUALISIEREN Im Allgemeinen ist die Rückgabe eines Paares schneller, wenn der Compiler das @ optimierstd::pair
Methoden (Beispiele für Binärausgabe mitGCC 5.3.0 undClang 3.8.0). Obf()
ist nicht inline, der Compiler muss Code generieren, um einen Wert in den Speicher zu schreiben, z. B .:
movq b, (%rdi)
movq a, %rax
retq
Aber im Falle vong()
es genügt für den Compiler zu tun:
movq a, %rax
movq b, %rdx
retq
Da Anweisungen zum Schreiben von Werten in den Speicher im Allgemeinen langsamer sind als Anweisungen zum Schreiben von Werten in Register, sollte die zweite Version schneller sein.