2015-07-15 7 views
0

Естественно, я предположил, что операторы < и < = работают с одинаковой скоростью (per Jonathon Reinhart's logic, here). Недавно я решил проверить это предположение, и я был немного удивлен моими результатами.Почему <будет медленнее, чем <=? [C]

Я знаю, что для большинства современных аппаратных средств этот вопрос носит чисто академический характер, поэтому ему приходилось писать тестовые программы, которые занимали около 1 миллиарда раз (чтобы получить любую незначительную разницу, чтобы добавить более приемлемые уровни). Программы были как можно более простыми (чтобы вырезать все возможные источники помех).

lt.c:

int main() { 
    for (int i = 0; i < 1000000001; i++); 

    return 0; 
} 

le.c:

int main() { 
    for (int i = 0; i <= 1000000000; i++); 

    return 0; 
} 

Они были собраны и работают на Linux VirtualBox 3.19.0-18-родового # 18- Ubuntu x86_64 установка с использованием GCC с -std = c11 набор флагов.

Среднее время двоичного lt.c было:

real 0m2.404s 
user 0m2.389s 
sys 0m0.000s 

Среднее время le.c было:

real 0m2.397s 
user 0m2.384s 
sys 0m0.000s 

Разница невелика, но я не мог заставить его уйти или отменить независимо от того, сколько раз я запускал двоичные файлы.

  • Я сделал сравнительное значение в цикле for lt.c больше, чем le.c (так что оба цикла будут одинаковыми). Это было как-то ошибкой?
  • По ответам Is < faster than <=?, < компилируется в jge и <= компилируется в jg. Это касалось if-выражений, а не for-loop, но может ли это быть причиной? Может ли выполнение jge взять немного больше, чем jg? (Я думаю, что это было бы иронично, так как это означало бы переход от C к ASM-инвертированию, который является более сложной инструкцией, причем lt в C переводят на gte в ASM и lte на gt.)
  • Или это просто поэтому аппаратная особенность, что разные линии x86 или отдельные чипы могут постоянно показывать обратную тенденцию, ту же тенденцию или разницу?
+3

Вы можете попросить компилятор дать вам код на ассемблере и изучить что. –

+6

Оба кода составляют одну и ту же сборку (оба с 'jle'), даже с -O0 (gcc 4.9.2). Разница, вероятно, неконтролируемая артефакт. – ElderBug

+2

Используя '-O3', компилятор должен был оптимизировать петли, а использование оптимизации не имеет смысла. –

ответ

1

В комментарии к моему вопросу было добавлено несколько запросов, чтобы включить сборку, созданную для меня GCC. Получив компилятор, чтобы вытащить версии сборки каждого файла, я проверил его.

Результат:
Оказывается, настройка оптимизации по умолчанию оказалось как для лупов в одну сборку. На самом деле оба файла были идентичны в сборке. (diff подтвердил это.)

Возможная причина разницы ранее наблюдаемого времени:
кажется порядок, в котором я выбежала бинарники был причиной разницы во времени запуска.

  • В ходе данного прогона программы, как правило, выполнялись быстрее с каждым последующим исполнением до планования после примерно 3 казней.
  • Я чередовался взад и вперед между time ./lt и time ./le, поэтому первый запуск будет иметь предвзятое отношение к дополнительному времени в среднем.
  • Я обычно побежал первым.
  • Я сделал несколько отдельных проходов (увеличение усредненного смещения).

фрагмент кода:

 movl $0, -4(%rbp) 
     jmp  .L2 
.L3: 
     addl $1, -4($rbp) 
.L2 
     cmpl $1000000000, -4(%rbp) 
     jle  .L3 
     mol  $0, %eax 
     pop  %rbp 

... * Крышки сталкиваются * ... продолжать ....

+3

Теперь вы знаете больше о механизме кэша команд процессора и о том, что он делает :) – Cobusve

0

Давайте говорить в сборе. (в зависимости от архитектуры, конечно) При сравнении вы будете использовать инструкцию cmp или test, а затем - когда вы используете <, команда равенства будет jl, которая проверяет, не являются ли SF и OF (одни специальные флаги с именем sign и overflow) - когда вы используете < = равная инструкция jle, которая проверяет не только SF! = OF, но также ZF == 1 (флаг нуля) и поэтому один, более here , но, честно говоря, это даже не весь цикл. .. Я думаю, что разница неизмерима при нормальных обстоятельствах.

 Смежные вопросы

  • Нет связанных вопросов^_^