Ich versuche, eine zeilenlose Funktion zu schreiben, um die MAX oder MIN von zwei Ganzzahlen zurückgeben, ohne auf if (oder? :). the usual technique ich mit dieser leicht genug für ein gegebenes Wort Größe tun können:Templazed Zweiglos Int Max/Min-Funktion
inline int32 imax(int32 a, int32 b)
{
// signed for arithmetic shift
int32 mask = a - b;
// mask < 0 means MSB is 1.
return a + ((b - a) & (mask >> 31));
}
Wenn man nun annimmt arguendo, dass ich wirklich die Art von Anwendung auf die Art von in-Order-Prozessor, wo dies notwendig ist, meine Frage schreibe ist Gibt es eine Möglichkeit, C++ - Vorlagen zu verwenden, um dies auf alle Größen von int zu verallgemeinern?
Der >> 31 Schritt funktioniert natürlich nur für Int32s, und während ich Überladungen auf die Funktion für int8, int16 und int64 kopieren konnte, scheint es, dass ich stattdessen eine Template-Funktion verwenden sollte. Aber wie bekomme ich die Größe eines Template-Arguments in Bits?
Gibt es einen besseren Weg, dies zu tun? Kann ich die Unterschrift der Maske T erzwingen? Wenn T nicht vorzeichenbehaftet ist, wird der Maskenverschiebungsschritt nicht funktionieren (weil es eine logische statt einer arithmetischen Verschiebung ist).
template< typename T >
inline T imax(T a, T b)
{
// how can I force this T to be signed?
T mask = a - b;
// I hope the compiler turns the math below into an immediate constant!
mask = mask >> ((sizeof(T) * 8) - 1);
return a + ((b - a) & mask);
}
Und die oben getan zu haben, kann ich verhindern, dass es aber einen Integer-Typ für alles verwendet werden (zB keine Schwimmer oder Klassen)?
Die meisten modernen Maschinen haben Konditional mov Anweisungen, die ihnen ermöglichen, ohne Äste min/max zu tun (z. B. cmp a, b/movlt a, b). Dies wäre schneller als der Code, den Sie generieren möchten, und die Compiler kennen sie. Bist du sicher, dass dein Compiler das nicht schon für dich tut? –
@IraBaxter Absolut sicher; Ich schaue immer auf seine Montageausgabe. Auch der Zielprozessor (ein PowerPC-Derivat) hat definitiv kein cmov. – Crashworks
Egal welchen Code Sie schreiben, er wird nur als C++ - Quelle abzweigfrei sein. Der Compiler kann bedingte Sprünge (dh Verzweigungen) erzeugen, ohne if/else /? /: Zu schreiben, und umgekehrt kann er optimierte verzweigungsfreie Instruktionen von der if/else-Quelle erzeugen. – galinette