Was entspricht der Funktionsparameter constexpr?
Wir versuchen, Code unter Clang und Visual C ++ zu beschleunigen (GCC und ICC sind in Ordnung). Wirhabe gedach wir könnten @ verwendconstexpr
um Clang mitzuteilen, dass ein Wert eine Kompilierzeitkonstante ist, die jedoch einen Kompilierfehler verursacht:
$ clang++ -g2 -O3 -std=c++11 test.cxx -o test.exe
test.cxx:11:46: error: function parameter cannot be constexpr
unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
^
1 error generated.
Hier ist der reduzierte Fall:
$ cat test.cxx
#include <iostream>
unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate);
int main(int argc, char* argv[])
{
std::cout << "Rotated: " << RightRotate(argc, 2) << std::endl;
return 0;
}
unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
{
// x = value; y = rotate
__asm__ ("rorl %1, %0" : "+mq" (value) : "I" ((unsigned char)rotate));
return value;
}
GCC und ICC werden das Richtige tun. Sie erkennen einen Wert wie2
im AusdruckRightRotate(argc, 2)
kann sich unter den Gesetzen des physikalischen Universums, wie wir sie kennen, nicht ändern, und es wird @ behande2
als Kompilierzeitkonstante und in den Assembler-Code übernehmen.
Wenn wir das @ entfernconstexpr
, dann zerlegt Clang und VC ++ die Funktion in einrotate REGISTER
, was bis zu 3x langsamer ist als einrotate IMMEDIATE
.
Wie sagen wir Clang den Funktionsparameterrotate
ist eine Kompilierzeitkonstante und sollte zu einem @ zusammengesetzt werdrotate IMMEDIATE
eher als einrotate REGISTER
?