User Tag List

Показано с 1 по 10 из 180

Тема: Почему компилированный Бейсик выполняется быстро?

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,089
    Спасибо Благодарностей отдано 
    281
    Спасибо Благодарностей получено 
    70
    Поблагодарили
    49 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от vlad-kras Посмотреть сообщение
    Берем программу на бейсике, компилируем и она ускоряется ... в несколько раз.
    Да, это опьяняет - поначалу. Но всё равно, это ускорение - ничто по сравнению с тем, что можно получить, программируя на ассемблере.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    А почему так сильно ускорается, в несколько раз? Часто пишут, что интерпретатору сначала надо проанализировать программу.
    Да, надо проанализировать. Синтаксический анализ - очень непростая тема. Особенно, когда начинаешь думать, какие сложные варианты конструкций языка программирования могут встретиться, и их все интерпретатор должен правильно понять и обработать.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    Но он (наверное) программу, выполняет по строчкам, как разные источники пишут. То есть берет из строки по одной команде, анализирует что за команда и переводит в машинный код.
    По командам, если точнее. В одной строке могут встретиться несколько команд, разделенных двоеточием. Как только интерпретатор доходит до конца команды (последней в строке, или отделенной двоеточием от следующих команд) - то он ее выполняет. Потом переходит к следующей. Принципиальных отличий строк от команд два:
    1) На строку можно перейти командой GOTO или GOSUB (исполнение продолжится с первой команды в строке, на которую переходит GOTO/GOSUB). На отдельную (не первую) команду в строке прямо перейти нельзя - нет таких команд. Хотя можно вернуться на вторую и последующие команды в строке с помощью RETURN.
    2) Команда REM делает всё, что стоит в строке после нее, недостижимым для исполнения интерпретатором, и потому является последней в строке, где она встретилась.

    Интерпретатор не переводит программу в машинный код. Он ее анализирует и, по мере анализа, исполняет действия, которые требуется. Например, встретилась команда BEEP - интерпретатор анализирует её параметры и вызывает подпрограмму в машинных кодах, которая издаёт звук. Встретилась команда DRAW - интерпретатор анализирует параметры и вызывает подпрограмму рисования линии в машинных кодах.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    И вот вопрос - неужели интерпретатор самую большую часть времени тратит просто на анализ текста,
    Да, это занимает львиную долю процессорного времени. Анализ текста программы - трудная задача. Большинство профессиональных программистов нашего времени не умеют ее решать эффективно и без ошибок. Учили когда-то в университете основы теории, но благополучно забыли и на практике не используют. Попробуй, ради интереса, написать на любом языке программирования, программу вычисления выражений, заданных формулами в текстовом виде. Сразу прочувствуешь всю глубину транса.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    может еще какие технические причины есть для ускорения?
    Да, есть и еще причины.

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

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

    Наконец, не все подпрограммы действия в машинных кодах эффективны. В свое время я занимался переделкой Спектрум-бейсика, и удалось ускорить исполнение команды CIRCLE в разы, применив более эффективный алгоритм.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    Например по операторам, в спектруме ключевые слова это же токены, а не строки букв. Значит надо проанализировать не всю строку до пробела, а всего 1 байт и понятно будет что за оператор - для ABS и CLS 1 байт вместо 3 букв, а для PAUSE 5 и RANDOMIZE 9 букв. И кроме того сразу можно сделать таблицу соответствия токен -- адрес его обработки, тогда переход к подпрограмме обработки оператора должен будет выполняться за время о(1), т.е. независимо от числа возможных токенов.
    Токенизация строк - это очень важный момент, и если бы ее не было - то бейсик работал бы в разы медленнее. Большинство интерпретаторов бейсика используют токенизацию для внутреннего представления программы, даже те, где надо набивать операторы по буквам, и токенизации как бы не видно.

    Но не токенизацией единой. Кроме самих команд, надо еще обрабатывать параметры, переводить в двоичную форму числа и вычислять выражения. Даже с числами в Спектрум-бейсике применяется трюк: внутреннее представление программы содержит числовые константы в предварительно интерпретированном, двоичном виде. Это внутреннее представление может отличаться от текстового. С этим связан хакерский трюк: реальные числа, с которыми работает программа, могут отличаться от отображаемых, если над внутренним представлением программы провести манипуляции. В программе может стоять команда RANDOMIZE USR 0, но при ее выполнении не произойдет сброс, как ожидается, а будет вызван машинный код совсем с другого адреса.

    Но даже и предварительное преобразование числовых констант не решает все проблемы быстродействия. Для вычисления выражений все равно приходится использовать сложные процедуры, которые долго исполняются. А компилятор может один раз проверить синтаксис и преобразовать любое выражение в обратную польскую запись. Даже при сохранении затрат на собственно математические операции, это может в разы повысить быстродействие.
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    Ну ладно, я не знаю как внутри обработка в ROM устроено, может даже не сделали таблицу и выполняют сравнение токенов по цепочке if 200 else if 201 else if 202 итд.
    Конечно, там сделали таблицу. Авторы бейсика, хоть и не боги, но вполне хорошие и опытные программисты уровня гораздо выше среднего (особенно в сравнении с нашим временем). У них можно многому поучиться. Для меня в свое время анализ интерпретатора Спектрум-бейсика был хорошей школой. Два добрых человека Ian Logan & Frank O'Hara провели полное дизассемблирование, анализ и комментирование Спектрум-бейсика, и издали результаты в виде книги. Там каждая команда разжевана, все идеи и алгоритмы расписаны. Очень рекомендую. Гугл в помощь. Был и русский перевод. "Ян логан, Френк о хара"
    Цитата Сообщение от vlad-kras Посмотреть сообщение
    Потом подумал, что еще другие моменты есть. Например, интерпретатор все время опрашивает клавиатуру на предмет нажатия BREAK, а компилированный код не опрашивает - или тоже опрашивает?
    Это от компилятора зависит. Большинство не опрашивают. Но такой опрос не занимает много процессорного времени, даже, если он есть.

    Эти 4 пользователя(ей) поблагодарили Barmaley_m за это полезное сообщение:

    Kubas(14.11.2023), mastermind(11.12.2022), Reobne(04.12.2022), vlad-kras(03.12.2022)

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2

    Регистрация
    06.11.2020
    Адрес
    г. Санкт-Петербург
    Сообщений
    167
    Спасибо Благодарностей отдано 
    80
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    23 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  4. #3

    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,089
    Спасибо Благодарностей отдано 
    281
    Спасибо Благодарностей получено 
    70
    Поблагодарили
    49 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Спасибо за хорошие отзывы. Хочу немного уточнить, сразу не все вспомнилось.
    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    На отдельную (не первую) команду в строке прямо перейти нельзя - нет таких команд. Хотя можно вернуться на вторую и последующие команды в строке с помощью RETURN.
    Не только RETURN, а еще NEXT и CONTINUE.
    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    Да, есть и еще причины.
    Еще одна причина - это поиск переменных. Бейсик по сути хранит базу данных всех переменных, с которыми работает программа. При каждом обращении к переменной происходит ее поиск по имени в этой базе. Уже забыл, какой там используется алгоритм, как бы не линейный поиск. Чем больше переменных, тем медленнее работает программа. И скорость ее работы зависит от того, какие дать имена переменным, которые часто используются.
    Последний раз редактировалось Barmaley_m; 05.12.2022 в 23:57.

    Этот пользователь поблагодарил Barmaley_m за это полезное сообщение:

    Reobne(06.12.2022)

  5. #4

    Регистрация
    27.02.2005
    Адрес
    москва
    Сообщений
    14,292
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    203
    Спасибо Благодарностей получено 
    1,456
    Поблагодарили
    946 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    В компилированной программе можно заранее (на этапе компиляции) рассчитать в памяти место программы, откуда надо продолжить исполнение. Кроме случая "косвенного перехода", когда параметром GOTO или GOSUB является не константа, а переменная или математическое выражение с переменными. Но последний случай не поддерживается большинством компиляторов бейсика. Его поддержка обошлась бы сложно и дорого (по времени исполнения).
    первый-же проверенный компилятор (от Hisoft1988г.) спокойно поддерживает такой приём.
    Последний раз редактировалось goodboy; 06.12.2022 в 00:13.

    Эти 2 пользователя(ей) поблагодарили goodboy за это полезное сообщение:

    Barmaley_m(20.12.2022), Reobne(06.12.2022)

  6. #5

    Регистрация
    26.09.2009
    Адрес
    г. Красноярск
    Сообщений
    3,198
    Спасибо Благодарностей отдано 
    40
    Спасибо Благодарностей получено 
    128
    Поблагодарили
    103 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    goodboy, Тут как бы, палка о двух концах. Быстродействие или полнота поддержки синтаксиса. Плюс, размер библиотек компилятора в памяти.
    Последний раз редактировалось null_device; 01.11.2023 в 07:57.
    Когда есть, но не знаешь где - это все равно, что нету.

    Этот пользователь поблагодарил null_device за это полезное сообщение:

    Barmaley_m(04.11.2023)

  7. #6

    Регистрация
    08.09.2005
    Адрес
    Воронеж
    Сообщений
    4,964
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    319
    Спасибо Благодарностей получено 
    313
    Поблагодарили
    237 сообщений
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    Конечно, там сделали таблицу.
    аж два уровня, и это еще до разбора выражений-параметров

    собс-но вот, страница 84 -
    http://www.primrosebank.net/computer...ssemblyThe.pdf
    Прихожу без разрешения, сею смерть и разрушение...

    Эти 2 пользователя(ей) поблагодарили Lethargeek за это полезное сообщение:

    Barmaley_m(07.12.2022), mastermind(11.12.2022)

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 47
    Последнее: 02.02.2021, 14:06
  2. Как быстро летит время.
    от Mick в разделе Новости
    Ответов: 18
    Последнее: 25.02.2020, 08:43
  3. Почему Спектрум-бейсик такой медленный?
    от mmxdmv в разделе ZX Концепции
    Ответов: 53
    Последнее: 07.07.2018, 19:39
  4. Как быстро добраться до мыши?
    от TomCaT в разделе Для начинающих
    Ответов: 38
    Последнее: 02.03.2010, 11:00
  5. Быстро переместить 384b
    от Aprisobal в разделе Программирование
    Ответов: 6
    Последнее: 23.01.2005, 15:23

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •