C ++ 11 schnelle Constexpr Integer-Potenzen
Hier das tote Pferd schlagen. Ein typischer (und schneller) Weg, ganzzahlige Potenzen in C auszuführen, ist dieser Klassiker:
int64_t ipow(int64_t base, int exp){
int64_t result = 1;
while(exp){
if(exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
Ich benötigte jedoch eine ganzzahlige Potenz zur Kompilierungszeit, also fuhr ich fort und führte eine rekursive Implementierung mit constexpr durch:
constexpr int64_t ipow_(int base, int exp){
return exp > 1 ? ipow_(base, (exp>>1) + (exp&1)) * ipow_(base, exp>>1) : base;
}
constexpr int64_t ipow(int base, int exp){
return exp < 1 ? 1 : ipow_(base, exp);
}
Die zweite Funktion besteht nur darin, Exponenten kleiner als 1 vorhersehbar zu behandeln. Vorbeigehenexp<0
ist ein Fehler in diesem Fall.
Ich generiere einen Vektor aus 10E6 zufällig bewerteten Basen und Exponenten im Bereich [0,15] und stelle beide Algorithmen auf dem Vektor zeitlich fest (nachdem ich einen nicht zeitgesteuerten Lauf durchgeführt habe, um zu versuchen, Caching-Effekte zu entfernen). Ohne Optimierung ist die Rekursionsmethode doppelt so schnell wie die Schleife. Aber mit -O3 (GCC) ist die Schleife viermal schneller als die Rekursionsmethode.
Meine Frage an euch lautet: Kann mir jemand eine schnellere ipow () - Funktion einfallen lassen, die Exponenten und Basen von 0 behandelt und alsconstexpr
?
(Haftungsausschluss: Ich nichtbrauchen ein schnelleres ipow, ich bin nur daran interessiert zu sehen, was die schlauen leute hier einfallen lassen können).