Действительно ли языки программирования и методы неэффективны? (ассемблер и необходимое знание C)

в течение долгого времени я думаю и изучаю вывод компилятора языка C в ассемблерной форме, а также архитектуру ЦП. Я знаю, что это может быть глупо Вам, но мне кажется, что что-то очень неэффективно. Не будьте сердиты, если я неправ, и существует некоторая причина, я не вижу все эти принципы. Я буду очень рад, если Вы скажете мне, почему это разработано этот путь. Я на самом деле действительно полагаю, что я неправ, я знаю умы гения людей, которые собираются, ПК знали причину, чтобы сделать так. Что точно, Вы спрашиваете? Я скажу Вам сразу же, я использую C в качестве примера:

1: Сложите локальное выделение памяти объема:

Так, типичное выделение локальной памяти использует стек. Просто ESP копии к ebp и, чем выделяет всю память через ebp. Хорошо, я понял бы это, если Вы явно должны выделить RAM значениями стека по умолчанию, но если я действительно понимаю это правильно, современная подкачка страниц использования ОС как слой перевода между приложением и физической RAM, когда адрес Вы требуете, далее переводится прежде, чем достигнуть фактического байта RAM. Итак, почему только не говорят, что 0x00000000 является интервалом a, 0x00000004 является интервалом b и так? И доступ их только mov 0x00000000, #10? Поскольку Вы привычка на самом деле блоки памяти 0x00000000 и 0x00000004 доступа, но те Ваш ОС устанавливаете таблицы пейджинга на. На самом деле, начиная с выделения памяти ebp и особенно используют косвенную адресацию, "мой" путь был бы еще быстрее.

2: Переменная двуличность выделения:

Когда Вы запускаете приложение, загрузка Загрузчика его код в RAM. При создании переменной или строки компилятор генерирует код, который продвигает эти значения на вершине o стек при создании в основном. Таким образом, существует фактическая инструкция для, делают так, и что фактическое число в памяти. Так, существует 2 записи того же значения в RAM. Один в форме инструкции, второй в форме фактических байтов в RAM. Но почему? Почему не к тому, как раз в то самое время, когда объявление переменного количества, в котором блоке памяти это было бы, чем тогда, когда используется, просто вставляет эту ячейку памяти?

10
задан starblue 17 June 2010 в 07:27
поделиться

5 ответов

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

  2. Похоже, вы хотите поведение языка C (или, по крайней мере, то, что позволяет C) для строковых литералов. В этом есть свои плюсы и минусы, например, тот факт, что даже если вы определили "переменную", вы не можете фактически изменить ее содержимое (не затрагивая другие переменные, которые указывают на то же место).

6
ответ дан 3 December 2019 в 15:21
поделиться

Ответы на ваши вопросы в основном связаны с различной семантикой разных классов хранения

  • Google "сегмент данных"
  • Подумайте о разнице в поведении между глобальными и локальными переменными.
  • Подумайте о том, насколько разные требования к постоянным и непостоянным переменным при многократном вызове функций (или , как говорит Мердад, рекурсивно).
  • Подумайте о разнице между статическими и нестатическими автоматическими переменными еще раз в контексте множественные или рекурсивные вызовы.
3
ответ дан 3 December 2019 в 15:21
поделиться

Как бы вы реализовали рекурсивные функции? То, что вы описываете, эквивалентно использованию глобальных переменных повсюду.

Это только одна проблема. Как вы можете ссылаться на предварительно скомпилированный объектный файл и быть уверенным, что он не испортит память ваших процедур?

.
17
ответ дан 3 December 2019 в 15:21
поделиться
  1. Если бы каждая функция помещала свою первую переменную по смещению 0 и так далее, то вам пришлось бы менять отображение памяти каждый раз, когда вы входите в функцию (вы не можете назначить всем переменным уникальные адреса, если хотите рекурсии). Это выполнимо, но с текущим аппаратным обеспечением это очень медленно. Кроме того, преобразование адресов, выполняемое виртуальной памятью, тоже не бесплатное, на самом деле это довольно сложно реализовать эффективно.
    Обращение к ebp (или любому другому регистру) требует наличия mux (для выбора регистра) и сумматора (для добавления смещения к регистру). Время, затрачиваемое на это, часто может перекрываться другими операциями.

  2. Если вы хотите иметь возможность изменять статическое значение, вы должны скопировать его в стек. Если вы этого не сделаете (сказав, что это 'const'), то хороший компилятор языка Си не скопирует его в стек.

1
ответ дан 3 December 2019 в 15:21
поделиться

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

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

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

2
ответ дан 3 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: