Das tote Pferd hier schlagen. Ein typischer (und schneller) Weg, ganzzahlige Kräfte in C zu tun, ist dieser Klassiker:
%Vor%Allerdings benötigte ich eine Kompilierzeit integer power, also ging ich voran und machte eine rekursive Implementierung mit constexpr:
%Vor% Die zweite Funktion besteht nur darin, Exponenten kleiner als 1 auf vorhersehbare Weise zu handhaben. Das Übergeben von exp<0
ist in diesem Fall ein Fehler.
Ich erzeuge einen Vektor aus 10E6 zufällig berechneten Basen und Exponenten im Bereich [0,15] und zeit beide Algorithmen auf dem Vektor (nach einem nicht zeitgesteuerten Lauf, um zu versuchen, irgendwelche Cache-Effekte zu entfernen). Ohne Optimierung ist die Rekursivmethode doppelt so schnell wie die Schleife. Aber mit -O3 (GCC) ist die Schleife 4 mal schneller als die rekursive Methode.
Meine Frage an euch ist folgende: Kann jemand eine schnellere ipow () Funktion entwickeln, die den Exponenten und die Basis von 0 behandelt und als constexpr
verwendet werden kann?
(Disclaimer: Ich brauche kein schnelleres ipow, ich bin nur daran interessiert zu sehen, was die klugen Leute hier finden können).
Ein guter optimierender Compiler verwandelt tail-recursive Funktionen so schnell wie imperative Code. Sie können diese Funktion so umwandeln, dass sie beim Pumpen pump-rekursiv ist. GCC 4.8.1 kompiliert dieses Testprogramm:
%Vor%in eine Schleife ( Siehe auf gcc.godbolt.org ):
%Vor%vs. Ihre while-Schleifenimplementierung :
%Vor%Anweisung für Anweisung identisch ist gut genug für mich.
Es scheint, dass dies ein Standardproblem bei der Programmierung von conexpr und Templates in C ++ ist. Aufgrund von Kompilierungszeitbeschränkungen ist die constexpr-Version langsamer als eine normale Version, wenn sie zur Laufzeit ausgeführt wird. Überladen erlaubt jedoch nicht, die richtige Version zu wählen. Der Normungsausschuss arbeitet an diesem Thema. Siehe zum Beispiel das folgende Arbeitsdokument Ссылка
Tags und Links optimization c++ c++11 recursion constexpr