Система Orphus

суббота, 4 июля 2009 г.

Архитектура x86 - очень странная

Это перевод The x86 architecture is the weirdo. Автор: Реймонд Чен.

Архитектура x86 делает множество вещей, которые не делает никакая другая современная архитектура, но из-за её ошеломляющей популярности люди думают, что x86 - это нормальный путь, а странные - это все остальные.

Давайте сразу прямо уточним: архитектура x86 является странной (x86 architecture is the weirdo).

x86 имеет небольшое количество (8) регистров общего назначения; другие современные процессоры имеют намного больше (PPC, MIPS и Alpha имеют по 32; у ia64 их 128).

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

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

x86 использует инструкции переменного размера. Остальные используют инструкции фиксированного размера (PPC, MIPS и Alpha используют инструкции в 32 бита ровно; ia64 использует инструкции длиной 41 бит каждая. Да, инструкции размером ровно 41 бит).

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

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

x86 передаёт адрес возврата в стеке. Остальные используют специальный регистр.

Имейте это ввиду, когда вы собираетесь писать переносимый код (portable code). Как и множество других вещей, культура, в которой вы выросли, кажется вам "нормальной", даже если, по сравнению с прочими, она является одной из самых выделяющихся.

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

Livithan комментирует...

x86 странная только без - т

Александр комментирует...

"x86 имеет небольшое количество (8) регистров"

Наверно, автор ведёт речь про 8086! ))) MMX, SSE, FPU - имеют свои регистры... Да и с изменением разрядности количество регистров процессора как-бы увеличилось, ведь мы можем работать с "половинками" обычных регистров.

"x86 использует стек для передачи параметров функциям; все прочие используют регистры."

ээээ... Это к архитектуре x86 никакого отношения не имеет, вообще-то... За это компилятор отвечает. Вот, в том-же паскале или дельфи использует передачу параметров именно по регистрам, хотя можно их передавать и по другому, используя специальные директивы компилятора (register, pascal, cdecl, stdcall, safecall и т.д.)

"x86 поддерживает атомарные операции типа загрузить-изменить-сохранить. Нигде больше такого нет."

Странно, даже в Z80 такие операции присутствовали! )))

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

GunSmoker комментирует...

>>> MMX, SSE, FPU - имеют свои регистры
Это - расширения.

>>> Да и с изменением разрядности количество регистров процессора как-бы увеличилось, ведь мы можем работать с "половинками" обычных регистров.
Обращение к половине регистра не делает его полноценным регистром. Новых регистров нет. Есть увеличение разрядности.

>>> Это к архитектуре x86 никакого отношения не имеет, вообще-то... За это компилятор отвечает
Да ну. Не путайте причину и следствие. Компилятор делает так, потому что это диктуется архитектурой. Архитектура - первична.
Посмотрите ещё эту серию и этот пост.

>>> Странно, даже в Z80 такие операции присутствовали! )))
Наверное, это не удивительно. Если учитывать, что Z80 был создан как клон 8080, ушедшими из Intel сотрудниками? Новый процессор изначально создавался совместимым с 8080 (с дополнительным набором команд).

>>> сложилось впечатления, что сравнивается CISC-архитектура с несколькими RISC-архитектурами
Да, именно так.
Наверное это потому, что сложно назвать другую распространённую CISC-архитектуру, кроме x86? ;) (на ум приходят только динозавры из 70-х). В то время, как RISC - это ARM (пример: Apple iPod, iPhone и т.п.), MIPS (PlayStation), Sun-ский SPARC и т.д.
x86 странная именно потому, что это CISC. В то время, как почти все другие архитектуры являются RISC. Да, с точки зрения другой архитектуры, странно всё то, что не совпадает с твоим собственным. Но в общей куче архитектур выделяется именно x86, а не другая. Об этом и пост.

P.S. Ну, внутренне новые x86 процессоры выполняются в определённом RISC-стиле, хотя внешний программный интерфейс не изменялся.

Александр комментирует...

"Это - расширения."

Блин, а чем расширения от "нерасширений" отличаются? Отличие, imho, только в терминалогии... По факту - это регистры, который камень использует...

"Да ну. Не путайте причину и следствие. Компилятор делает так, потому что это диктуется архитектурой. Архитектура - первична."

Ну да! В скобках я указал дерективы компилятора паскаля и делфей, которые используют другие способы передачи параметров. И, кстати, дельфи и "си билдер" по умолчанию всегда использует именно "register" передачу. Почему-то, им "архитектура процессора" в этом никак не мешает.
И первая ваша ссылка по "регистрам" описывает проц 8086, а вторая описывает соглашения, использующиеся ещё во времена MSDOS. Даже Delphi 1 под Win16, между своими процедурами и BPL'ками, параметры передавала регистрами (ну, если регистров хватало). Хотя, в статье там даже написано, что описывается 16-битные соглашения о вызовах - а сейчас обычно используются 32\64 битные программы.
Хотя, в сиподобных языках и библиотеках Windows данные передаются по стеку - но это не из-за архитектуры, а так просто исторически сложилось... Существуют ведь операционные системы Windows под "не х86-платформы"! Там ведь тоже данные между процедурами в библиотеках стеком передаются!

GunSmoker комментирует...

>>> Блин, а чем расширения от "нерасширений" отличаются?
В посте идёт речь об архитектуре x86. Я не знаю, зачем вы сюда приплетаете расширения. Расширение - это вполне самостоятельная и автономная единица, у неё своя архитектура. Например, MMX изначально разрабатывалась для RISC-процессора Intel i860 (её RISC-корни можно увидеть и сейчас). А FPU когда-то вообще был аппаратно другим процессором.
Нет, ради бога, если хотите - напишите сравнение архитектур вместе с расширениями (не забудьте тогда уж и расширения для RISC-процессоров - типа MDMX, MIPS-3D и т.п.) в настоящий момент. Только в формат/идею этого поста такое сравнение не будет укладываться. Это исторический пост.

>>> И первая ваша ссылка по "регистрам" описывает проц 8086
Первая ссылка идёт на серию постов.

>>> В скобках я указал дерективы компилятора паскаля и делфей, которые используют другие способы передачи параметров
Так, кажется я понял откуда сыр-бор. Вы неверно поняли фразу "x86 использует стек для передачи параметров функциям". Поясняю: эта фраза не означает, что в x86 ВООБЩЕ не используются регистры. Напротив, x86 как раз характеризуется наличием нескольких различных моделей вызовов (это более подробно описывается по ссылкам, приведённым выше), в некоторых из которых используются регистры. Указанную же фразу надо понимать так: другие архитектуры НЕ используют только стек для передачи параметров - они имеют единственную модель вызова, в которой параметры передаются регистрами (да, остаток - в стек, но всё равно там далеко не два-три регистра под параметры, а иногда десятки). Причём некоторые архитектуры не используют стек вообще, а только регистры (да, там есть регистровый стек, но это уже совсем другой зверь, аналога которому в x86 нет).

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

Просто этот пост есть краткое резюме других постов, поэтому тут изложено сжато. Чтобы не было недопониманий, надо читать предыдущие посты по моделям вызова - там некоторые моменты разжёвываются подробнее.

Анонимный комментирует...

> И, кстати, дельфи и "си билдер" по умолчанию всегда использует именно "register" передачу. Почему-то, им "архитектура процессора" в этом никак не мешает.

Чудак ты. Используют они это ровно потому, что это позволяет и _одобряет_ архитектура. А ну, попробуй мне передай параметры в регистрах, если это архитектурой не диктуется (к примеру, команда call обнуляет регистры или же свободных регистров нет, есть только preserved-регистры).

netch комментирует...

> x86 поддерживает атомарные операции типа загрузить-изменить-сохранить. Нигде больше такого нет.

Неправда, Sparc тоже использует CAS. У остальных перечисленных действительно LL/SC.

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

GunSmoker комментирует...

Да вроде как это не страшилки?

netch комментирует...

> Да вроде как это не страшилки?

Ассемблерщикам и системщикам всё равно менять большинство привычек даже при переходе на amd64, а прикладникам почти всё тут описанное - пофиг. Особенно количество регистров, да будь их хоть 2 хоть 100, кэш сейчас нивелирует разницу.

Из того, что таки всплывёт в ближайшее время - это lock-free/wait-free/etc. алгоритмы, для которых важно именно отношение к упорядочению операций в памяти. Код для x86 не будет работать на RISC из-за отсутствия явного указания release semantics или другой подобной спецификации доступа. Но и то это крайне малое количество авторов.

GunSmoker комментирует...

Я имел ввиду, что это исторический обзор, а не практическое руководство.


Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.