Не должно быть заметной разницы между сравнением разных предикатов из-за способа их вычисления (будьте осторожны, я не читал руководства по x86 подробно, поэтому он может работать по-разному):
Большинство инструкций производят несколько флагов в качестве побочного продукта, обычно у вас есть по крайней мере: carry (c), overflow (o), ноль (z) и минус (n).
Используя те предикаты, которые созданы инструкцией x-y (которая надежно создает вышеприведенные 4), мы можем легко вычислить все требуемые сравнения тривиально. Для чисел без знака:
x = y z
x != y !z
x < y !c
x <= y !c + z
x > y c . !z
x >= y c
Так что это вряд ли имеет значение. Но тогда есть некоторые различия, которые в основном сводятся к тому факту, что мы можем использовать TEST (который является AND вместо полного вычитания) или использовать CMP (это вычитание). ТЕСТ более ограничен, но быстрее (обычно).
Также современные архитектуры (начиная с c2d на стороне Intel) могут иногда объединять два микроопы в один макрооператор - так называемое макрооперационное слияние, которое имеет некоторые приятные преимущества. И правила для этого меняются от одной архитектуры к другой и немного длиннее. Например, ветви, которые проверяют только переполнение, четность или флаг знака (JO, JNO, JP, JNP, JS, JNS), могут соединиться с TEST, но не с CMP на c2d и nehalems (, держите пари, я посмотрел этот вверх - раздел 7.5 ).
Так можем ли мы просто сказать, что это сложно, и не беспокоиться о таких вещах? Это за исключением того, что вы пишете оптимизатор для компилятора, потому что на самом деле - независимо от того, ЧТО вы пишете в исходном коде, компилятор все равно будет делать то, что ему нужно - и по уважительной причине (т. Е. Если бы JGE был теоретически быстрее, вы бы имели написать, если (x