Donc, nous savons tous que le C/C++ signé/non signé règles de comparaison où -1 > 2u == true
, et j'ai une situation où je veux en œuvre correcte des comparaisons de manière efficace.
Ma question est, qui est plus efficace avec des considérations comme de nombreuses architectures de gens sont familiers avec. Évidemment, Intel et ARM ont plus de poids.
Donnée:
int x;
unsigned int y;
if (x < y) {}
Est-il préférable de promouvoir:
x < y => (int64)x < (int64)y
ou est-il préférable d'effectuer 2 comparaisons, c'est à dire:
x < y => (x < 0 || x < y)
L'ancien implique zéro, de proroger, de signe-les étendre, et une comparaison+branche, et ce dernier ne nécessite aucun signe d'étendre les opérations, mais 2 consécutifs cmp+branches.
La sagesse traditionnelle suggère que les branches sont plus chers que le signe s'étend, ce qui permettra à la fois de pipeline, mais il y a un décrochage entre la prolonge et la seule comparaison dans le premier cas, tandis que dans le second cas, je peux imaginer que certaines architectures pipeline pourrait le 2 comparaisons, mais ensuite suivi par 2 branches conditionnelles?
Un autre cas, où la valeur non signée est un type plus petit que le type signé, ce qui signifie qu'il peut être fait avec un seul zéro-étendre jusqu'à la signature du type de la longueur, puis une seule comparaison... dans ce cas, est-il préférable d'utiliser le prolonger+cmp version, ou est le 2-méthode de comparaison de toujours préféré?
Intel? BRAS? Les autres? Je ne sais pas si il y a un droit de réponse ici, mais je voudrais entendre les peuples prennent de l'. Faible niveau de performance est difficile de prévoir ces jours, en particulier sur les processeurs Intel et de plus en plus sur les BRAS.
Edit:
Je dois ajouter, il y a une évidence de la résolution, où les types sont de taille égale à l'architecture int largeur; dans ce cas, il est évident que le 2-comparaison de la solution est à privilégier, car la promotion elle-même ne peut pas être effectuée de manière efficace. Clairement mon int
exemple remplit cette condition pour les architectures 32 bits, et vous pouvez transposer l'expérience de pensée d' short
pour l'exercice appliqué à 32 bits plates-formes.
Edit 2:
Désolé, j'ai oublié l' u
en -1 > 2u
! >_<
Edit 3:
Je veux modifier la situation de supposer que le résultat de la comparaison d'une succursale, et le résultat n'est PAS retourné comme un booléen. C'est de cette façon je préfère la structure de regarder; bien que cela soulève un point intéressant qu'il existe un autre ensemble de permutations lorsque le résultat est un booléen vs une branche.
int g;
void fun(int x, unsigned in y) { if((long long)x < (long long)y) g = 10; }
void gun(int x, unsigned in y) { if(x < 0 || x < y) g = 10; }
Ce produit destiné à la branche généralement implicite lorsque vous rencontrez une if
;)