LINUX.ORG.RU

Компиляция для самых маленьких

 , ,


0

2

Всем привет и с наступающим Новым Годом :)

Объясните «популярно», пожалуйста, какая разница между python -m py_compile «%f» и gcc source.c, и что такое вообще «машинный код», а что «байт-код»? И почему source.pyc это исполняемый python байт-код, а а.out — исполняемый, кроме того, что к a.out дописан этот байт.


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

anonymous_sapiens ★★★★ ()

man архитектура_процессора
Машинный код выполняет твой процессор, а байт-код транслируется виртуальной машиной в команды твоего процессора.

CYB3R ★★★★★ ()

Собственно, всё уже сказали. Чуть более точно:

  • исходный код - человекочитаемый (plain text), прямому исполнению не подлежит (надо скомпилировать)
  • байт-код - машиночитаемый (бинарный), прямому исполнению не подлежит (надо запускать в интерпретаторе)
  • машинный код - машиночитаемый (бинарый), подлежит исполнению на процессоре

Иногда исходный код интерпретируется напрямую (python source.py), но внутри всё равно происходит трансляция в почти_байт-код.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

Спасибо за пояснения. А как насчет PyPy? Что такое Jit-компиляция?

Pa ()
Ответ на: комментарий от anonymous_sapiens

байт код не зависит от архитектуры процессора

это _нормальный_ байткод не зависит.....

stevejobs ★★★★★ ()
Ответ на: комментарий от Pa

JIT - это особый вид интерпретации, когда байт-код непосредственно перед исполнением компилируется в машинный код, и исполняется уже машинный. Причём компилируется по кускам: грубо говоря, при первом вызове функции foo() она компилируется, результат кладётся в кэш и сразу же выполняется.

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

intelfx ★★★★★ ()
Ответ на: комментарий от stevejobs

Если байт-код зависит от CPU, то толку от такого байт-кода ноль. :)

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Реквестирую пруфлинки что у питона и llvm байт-код машино-зависим. По-моему, ты не прав.

true_admin ★★★★★ ()
Ответ на: комментарий от stevejobs

Пробовал, потому и прошу «популярно» объяснить что к чему.

Pa ()
Ответ на: комментарий от true_admin

Ну давай включим логику. Что произойдет с ллвм если на целевой платформе поменяется размер указателей? ABI для внешних вызовов стопудово надо соблюдать. С floating point надо что-то делать. В цепочке lang->HIR->LIR->ASM, LIR вообще непортабелен. Любые сайзофы непортабельны. Даже при переходе в HIR делаются оптимизации, которые могут не заработать на другой платформе (заработать как-то не так), и технически нельзя будет отреверсить назад в изначальный lang так чтобы восстановить изначальный смысл и пересобрать.

Компромат на питонщиков надо спросить у питонщиков)

stevejobs ★★★★★ ()
Ответ на: комментарий от stevejobs

У питона подобных проблем нет, если он в нативщину не лезет.

PolarFox ★★★★★ ()
Ответ на: комментарий от intelfx

Jit — компилируется в машинный код, сохраняется в кэше (процессора?) чтобы потом повторно выполнится или при повторном запросе к foo() оно снова скомпилируется?

Pa ()
Ответ на: комментарий от Pa

Когда запускаешь прогу, «виртуальный процессор» (н-р JavaVM) выполняет твой байткод. При этом он может тормозить. Одновременно измеряется, какие куски программы выполняются чаще всего. Эти куски компилируются в код уже «реального» процессора, (н-р Intel Pentium). Реальный процессор может работать быстрее. Скорость проги повышается. Так понятно?

stevejobs ★★★★★ ()
Ответ на: комментарий от stevejobs

Так понятно?

Нет.

Байткод ведь выглядит как единицы и нули, машинный код выглядит так же? Ладно, я понял что бесперспективен. :(

Pa ()
Ответ на: комментарий от Pa

выражаясь гсм-но, единицы и нули, образующие узоры. Узоры разные. Каждый для своего дела. Какие конкретно дела - надо разбираться отдельно для каждого кода.

stevejobs ★★★★★ ()
Ответ на: комментарий от Pa

Не, кэш процессора - это сильно ниже. У интерпретатора есть свой «кэш» - т. е. место, куда кладутся скомпилированные куски, чтобы при повторном обращении к foo() не компилить заново, а исполнить сразу.

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

intelfx ★★★★★ ()
Ответ на: комментарий от Pa

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

aiive ()

В общем, ТС, суть в том, что байткод исполняет его интерпретатор (и только потом всё это исполняет процессор), а машинный код процессор выполняет напрямую.

Поэтому в спорах скриптобогов против компиляльщиков побеждают всегда компиляльщики.

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

Adonai ★★★ ()
Последнее исправление: Adonai (всего исправлений: 2)
Ответ на: комментарий от aiive

Ну вот ты все понял. Только для случая x86, то что называют машинным кодом, также является байт-кодом только его интерпретатор реализован уже в самом процессоре.

naszar ()
Ответ на: комментарий от stevejobs

об этом даже в факе есть

Там про C и C++. Никто не мешает тебе использовать фиксированные типы.

true_admin ★★★★★ ()
Ответ на: комментарий от stevejobs

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

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Есть два стула - на одном карандаши точёные Есть две платформы - на одной есть аппаратный floating point, на другой нету. Должен ли быть байткод одинаковым?

stevejobs ★★★★★ ()
Ответ на: комментарий от stevejobs

Должен ли быть байткод одинаковым?

У LLVM байткод пишется не для платформы, а для некого виртуального процессора. Там есть, например, поддержка 128-битных целых, причём, вне зависимости от того поддерживает ли это хост. Если что — будет сэмулировано.

В этом-то вся и фишка — байткод это всего лишь скомпилированный код на «языке llvm». Ты всегда можешь декомпилировать его через llvm-dis и получить ровно то же самое что и было. Или выполнить через lli (оно даже jit поддерживает).

true_admin ★★★★★ ()
Ответ на: комментарий от stevejobs

Есть две платформы - на одной есть аппаратный floating point, на другой нету. Должен ли быть байткод одинаковым?

до прохода floating-point/SIMD оптимизаторов - да.

Stil ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.