РЕДАКТИРОВАТЬ
Ответ ниже мини-интерпретирует вопрос ОП, который был конкретно о RUNTIME оптимизации, тогда как я исследовал оптимизацию времени компиляции.
Оригинальный ответ
Добавление к моему комментарию. До тех пор, пока у экспоненты будет int меньше или равно MAXINT, вы получите.
#include <cmath>
double pow(double a)
{
return std::pow(a, (int)2147483647);
}
генерирует
pow(double):
movapd xmm4, xmm0
mulsd xmm4, xmm0
movapd xmm5, xmm4
mulsd xmm5, xmm4
mulsd xmm4, xmm0
movapd xmm6, xmm5
mulsd xmm4, xmm5
mulsd xmm6, xmm5
movapd xmm3, xmm6
mulsd xmm3, xmm6
mulsd xmm3, xmm0
movapd xmm0, xmm4
movapd xmm2, xmm3
movapd xmm1, xmm3
mulsd xmm2, xmm6
mulsd xmm1, xmm3
mulsd xmm2, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm2
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm4
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm1, xmm1
mulsd xmm0, xmm1
ret
, но вы должны быть осторожны использовать int литерал
#include <cmath>
double pow(double a)
{
return std::pow(a, (unsigned int) 2147483647);
}
создает
pow(double):
movsd xmm1, QWORD PTR .LC0[rip]
jmp pow
.LC0:
.long 4290772992
.long 1105199103
РЕДАКТИРОВАТЬ
Кажется, я не прав. Выше был протестирован с ранней версией G CC. В ранних версиях G CC и CLANG умножение встроено. Однако в более поздних версиях этого не происходит. Вполне возможно, что более новые версии Если вы переключите версии на Godbolt, то вы увидите, что вышеприведенное НЕ ПРОИСХОДИТ.
Например,
#include <cmath>
double pow_v2(double a)
{
return std::pow(a, 2);
}
double pow_v3(double a)
{
return std::pow(a, 3);
}
для CLANG 10.0 генерирует
pow_v2(double): # @pow_v2(double)
mulsd xmm0, xmm0
ret
.LCPI1_0:
.quad 4613937818241073152 # double 3
pow_v3(double): # @pow_v3(double)
movsd xmm1, qword ptr [rip + .LCPI1_0] # xmm1 = mem[0],zero
jmp pow # TAILCALL
, но для CLANG 5.0 он генерирует
pow_v2(double): # @pow_v2(double)
mulsd xmm0, xmm0
ret
pow_v3(double): # @pow_v3(double)
movapd xmm1, xmm0
mulsd xmm1, xmm1
mulsd xmm1, xmm0
movapd xmm0, xmm1
ret
Кажется, что для более поздних версий компиляторов функция intrinsi c pow вызывается быстрее, чем встроенные умножения, поэтому компиляторы меняют свою стратегию.