Сколько asm-инструкций на C-инструкцию? - PullRequest
11 голосов
/ 01 декабря 2008

Я понимаю, что на этот вопрос невозможно ответить абсолютно, но я только после приблизительных цифр:

Учитывая C-программу разумного размера (тысячи строк кода), в среднем, сколько ASM-инструкций будет сгенерировано. Другими словами, каково реалистичное соотношение команд C-ASM? Не стесняйтесь делать предположения, такие как «с текущими архитектурами x86».

Я пытался узнать об этом в Google, но ничего не смог найти.

Добавление : отмечая, насколько путаница принесла этот вопрос, я чувствую некоторую потребность в объяснении: что я хотел бы узнать этим ответом, так это узнать, на практике, что означает "3GHz". Я полностью осознаю, что пропускная способность на Герц сильно варьируется в зависимости от архитектуры, вашего оборудования, кэшей, скорости шины и положения Луны.

Я не за точным и научным ответом, а скорее за эмпирическим ответом, который можно выразить в непостижимых масштабах.

Это не тривиальный ответ на место (как я стал замечать), и это было мое лучшее усилие в этом. Я знаю, что количество полученных строк ASM на строки C варьируется в зависимости от того, что вы делаете. i++ находится не в том же районе, что и sqrt(23.1) - я знаю это. Кроме того, независимо от того, какой ASM я получаю из C, ASM интерпретируется в различные наборы микрокода внутри процессора, что, опять же, зависит от того, используете ли вы AMD, Intel или что-то еще, и их соответствующие поколения. Я знаю об этом также.

Примерные ответы, которые я получил до сих пор, - это то, к чему я стремился: проект, достаточно большой, в среднем составляет около 2 строк x86 ASM на 1 строку ANSI-C. Сегодняшние процессоры, вероятно, в среднем будут составлять примерно одну команду ASM за такт, после того как конвейеры заполнены и дан достаточно большой образец.

Ответы [ 8 ]

21 голосов
/ 01 декабря 2008

Ответ невозможен. для операторов типа int a; может потребоваться ноль строк asm. в то время как для операторов типа a = call_is_inlined(); может потребоваться более 20 строк asm.

Вы можете увидеть себя, скомпилировав программу на c, а затем запустив objdump -Sd ./a.out. Он будет отображать смешанные коды asm и C, так что вы можете увидеть, сколько строк asm сгенерировано для одной строки C. Пример:

test.c

int get_int(int c);
int main(void) {
    int a = 1, b = 2;
    return getCode(a) + b;
}

$ gcc -c -g test.c

$ objdump -Sd ./test.o

00000000 <main>:
int get_int(int c);
int main(void) { /* here, the prologue creates the frame for main */
   0:   8d 4c 24 04             lea    0x4(%esp),%ecx
   4:   83 e4 f0                and    $0xfffffff0,%esp
   7:   ff 71 fc                pushl  -0x4(%ecx)
   a:   55                      push   %ebp
   b:   89 e5                   mov    %esp,%ebp
   d:   51                      push   %ecx
   e:   83 ec 14                sub    $0x14,%esp
    int a = 1, b = 2; /* setting up space for locals */
  11:   c7 45 f4 01 00 00 00    movl   $0x1,-0xc(%ebp)
  18:   c7 45 f8 02 00 00 00    movl   $0x2,-0x8(%ebp)
    return getCode(a) + b;
  1f:   8b 45 f4                mov    -0xc(%ebp),%eax
  22:   89 04 24                mov    %eax,(%esp)
  25:   e8 fc ff ff ff          call   26 <main+0x26>
  2a:   03 45 f8                add    -0x8(%ebp),%eax
} /* the epilogue runs, returning to the previous frame */
  2d:   83 c4 14                add    $0x14,%esp
  30:   59                      pop    %ecx
  31:   5d                      pop    %ebp
  32:   8d 61 fc                lea    -0x4(%ecx),%esp
  35:   c3                      ret
10 голосов
/ 01 декабря 2008

Я не уверен, что вы подразумеваете под "C-инструкцией", может быть, оператором или строкой? Конечно, это будет сильно отличаться из-за ряда факторов, но, посмотрев на несколько моих собственных программ, многие из них близки к отметке 2-1 (2 инструкции по сборке на LOC), я не знаю, что это значит или как это может быть полезно.

Вы можете сами понять это для любой конкретной программы и комбинации реализации, попросив компилятор генерировать только сборку (например, gcc -S) или используя дизассемблер на уже скомпилированном исполняемом файле (но вам потребуется исходный код чтобы сравнить это с так или иначе).

Редактировать

Просто подробно остановимся на этом, объяснив, что вы пытаетесь выполнить (понимая, сколько строк кода может выполнить современный процессор за секунду):

Хотя современный процессор может работать с 3 миллиардами циклов в секунду, это не значит, что он может выполнять 3 миллиарда команд в секунду. Вот некоторые вещи для рассмотрения:

  • Для выполнения многих инструкций требуется несколько циклов (операции деления или с плавающей запятой могут выполняться десятками циклов).
  • Большинство программ проводят большую часть своего времени в ожидании таких вещей, как доступ к памяти, доступ к диску и т. Д.
  • Многие другие факторы, включая издержки ОС (планирование, системные вызовы и т. Д.), Также являются ограничивающими факторами.

Но в целом да, процессоры невероятно быстры и могут достигать удивительных результатов за короткий промежуток времени.

4 голосов
/ 01 декабря 2008

Это сильно меняется! Я бы никому не поверил, если бы они попытались предложить грубое обращение.

Заявления типа i++; могут переводиться в один INC AX.

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

Затем добавьте туда оптимизацию компилятора, которая соберет ваш код способом, отличным от написанного вами, тем самым исключая инструкции.

Кроме того, некоторые инструкции лучше работают на границах машинных слов, поэтому NOP s будет отображаться во всем вашем коде.

3 голосов
/ 01 декабря 2008

Я не думаю, что вы можете сделать вывод что-нибудь полезное вообще о производительности реальных приложений из того, что вы пытаетесь сделать здесь. Если «не точное» означает «в пределах нескольких порядков».

Вы просто чрезмерно обобщены, и вы отказываетесь от кэширования и т. Д., Как если бы оно было вторичным, тогда как оно вполне может быть полностью доминирующим.

Если ваше приложение достаточно велико, чтобы иметь тенденцию к некоторому среднему количеству инструкций для каждого местоположения, то оно также будет достаточно большим, чтобы иметь операции ввода-вывода или, по меньшей мере, существенные проблемы с доступом к ОЗУ для учета.

2 голосов
/ 01 декабря 2008

В зависимости от вашей среды вы можете использовать опцию visual studio: / FAs

больше здесь

1 голос
/ 09 августа 2011

Вы написали в одном из комментариев, что хотите знать, что означает 3GHz.

Даже частота процессора не имеет значения. Современные ПК-процессоры интенсивно чередуют и планируют инструкции, они извлекают и предварительно выбирают, кэш-память и инструкции, и часто этот кэш аннулируется и выбрасывается в корзину. Лучшая интерпретация вычислительной мощности может быть получена при использовании реальных тестов производительности.

1 голос
/ 01 декабря 2008

RISC или CISC? Что такое инструкция в C, в любом случае?

То есть повторять вышеприведенные пункты, о которых вы действительно не подозреваете, пока не разберетесь с типом кода, с которым работаете.

Вы можете попытаться просмотреть академическую литературу, касающуюся оптимизации сборки и взаимных помех аппаратного / программного обеспечения, которые произошли за последние 30-40 лет. Вот где вы собираетесь найти какие-то реальные данные о том, что вас интересует. (Хотя я предупреждаю вас, вы можете увидеть данные C-> PDP вместо данных C-> IA-32).

1 голос
/ 01 декабря 2008

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

Что бы я сделал: возьмите программу на C разумного размера. Дайте gcc опцию "-S" и проверьте себя. Он сгенерирует исходный код на ассемблере, и вы можете сами рассчитать коэффициент для этой программы.

...