Как оптимизировать возвращаемые значения функций в C и C ++ на x86-64?
The x86-64 ABI определяет два регистра возврата:rax
а такжеrdx
, размером 64 бита (8 байт).
Предполагая, что x86-64 является единственной целевой платформой, какая из этих двух функций:
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 };
}
даст лучшую производительность, учитывая текущее состояние компиляторов C / C ++, нацеленных на x86-64? Есть ли подводные камни с точки зрения производительности при использовании той или иной версии? Всегда ли компиляторы (GCC, Clang) способны оптимизироватьstd::pair
возвращается вrax
а такжеrdx
?
ОБНОВИТЬ Обычно возврат пары происходит быстрее, если компилятор оптимизируетstd::pair
методы (примеры двоичного вывода с GCC 5.3.0 а такжеClang 3.8.0). Еслиf()
не встроен, компилятор должен сгенерировать код для записи значения в память, например:
movq b, (%rdi)
movq a, %rax
retq
Но в случаеg()
для этого достаточно компилятора:
movq a, %rax
movq b, %rdx
retq
Поскольку инструкции для записи значений в память обычно медленнее, чем инструкции для записи значений в регистры, вторая версия должна быть быстрее.