Comments 19
Довольно много неточностей и искажений -- явно из-за любви автора описываемому продукту. Вот несколько штук навскидку.
«Битность» процессора, например 8-битный или 32-битный, определяет, какой объем данных он может обрабатывать одновременно
Некорректно, если не добавить важное уточнение: с точки зрения программиста. Разрядность внутренних блоков, путей данных и т.д. и т.п. может быть любой. Скажем, сверхпопулярный в своё время Z80 имеет 4-разрядное АЛУ, хотя для программиста это 8-разрядный процессор. ЕС-1020, ЕС-1022, ЕС-1030 и ЕС-1050 реализуют одну и ту же архитектуру (32-разрядную IBM System/360), но у первой АЛУ 8-разрядное, у второй -- 16-разрядное, у третьей вообще дикая смесь всего (скажем, сумматор комбинация из 32- и 4-разрядного), а у четвёртой -- 64-разрядное, ну и так далее.
Чтобы обеспечить задел на будущее, было принято еще одно смелое решение — пропустить 16-битную стадию и сразу перейти к 32-битной архитектуре. Парадоксально, но это упрощало внутреннюю структуру чипа и реализацию прямого доступа ко всему адресному пространству памяти
Ничего парадоксального: либо ты сразу формируешь широкий адрес (кстати, у ранних АРМов он был, насколько помню, 26-разрядным), либо должен городить какую-то дополнительную аппаратуру для преобразования логических (виртуальных) адресов в физические. Правда, в конце концов всё равно городить пришлось, чтоб обеспечить поддержку виртуальной памяти, но это произошло намного позже (вроде, только в ARMv5).
Команда, состоявшая из менее чем десяти человек, создала сложнейший 32-битный RISC-процессор, который заработал безупречно с первой же попытки.
Он не сложнейший, он простейший. Проще почти что некуда -- собственно, это и стало одной из причин, почему удалось сходу сделать правильно. Плюс, конечно, нормально тестировали в процессе разработки (а вот Интел на это традиционно забивала, из-за чего, скажем, в 8086 команда инверсии не меняет флаги -- а должна была, как это делают все остальные команды обработки данных, ну а дальше уже приходится тащить сию "багофичу" из-за совместимости).
В нем отсутствовали кэш-память, аппаратные блоки для выполнения операций умножения и деления, а также модуль для вычислений с плавающей запятой, вместо которого использовалось устройство быстрого сдвига (barrel shifter).
...
В 1986 году увидела свет вторая версия процессора — ARM V2. В ней появилась поддержка сопроцессоров (например, для вычислений с плавающей запятой) и встроенные аппаратные схемы для операций умножения.
Аппаратное умножение отсутствовало даже в некоторых вариантах ARMv4, а деление появилось вообще лишь в ARMv7-M (а у микропроцессоров -- линейки -A -- оно отсутствует до сих пор; считается, что достаточно иметь FPU, который у -A есть, кажется, всегда).
И, кстати говоря, "устройство быстрого сдвига" никак не заменяет модуль для вычислений с плавающей запятой -- он лишь позволяет быстро производить многоразрядный сдвиг. Скажем, если команда требует сдвинуть значение на 5 разрядов, не надо пять раз выполнять однобитный сдвиг -- сразу будет выполнен требуемый. Вместе с некоторыми алгоритмическими трюками это позволяет ускорить подпрограммы, реализующие команды вещественной арифметики, но конкурировать с настоящим FPU всё равно не позволяет -- недаром его (FPU) в конце концов завезли даже в микроконтроллеры.
Искренне благодарю за такой экспертный и подробнейший фидбек!
в 8086 команда инверсии не меняет флаги -- а должна была, как это делают все остальные команды
это не баг, а именно фича. Технически NEG это "инвертировать все биты и добавить 1". А поскольку инверсные значения битов уже есть (у триггеров в регистрах есть и прямой, и инверсный выход), то NEG сводится к инструкции INC, применённой к инверсному выходу регистра аргумента.
Так вот, INC и DEC специально, by design, не устанавливают флаги (так что насчёт "все остальные команды" вы несколько погорячились). Во-первых, они используются в циклах, где их флаги мешали бы условию повторения цикла. А так вы можете вычислить любое сложное условие с данными по указателю и только потом увеличить указатель - флаги сохранятся.
Во-вторых, они неявно используются в микрокоде строковых инструкций (с префиксом REP). И здесь флаги от INC и DEC опять же мешали бы реализовать вещи типа REP CMPS, которая, например, реализует в одну инструкцию сишный strlen.
В-третьих, сама идея, что NEG именно обязан менять флаги, достаточно сомнительна. Вы всегда можете использовать обратные флаги до NEG.
"устройство быстрого сдвига" никак не заменяет модуль для вычислений с плавающей запятой
не заменяет, но значительно ускоряет программную эмуляцию. Прям в разы. Скажем, сложение и вычитание это именно сдвиги — перед, собственно, целочисленным сложением мантисс их нужно выровнять друг относительно друга (чтобы совпадала "точка").
И что самое смешное, barrel shifter позволяет реализовать целочисленное деление быстрее, чем его выполняли аппаратные делители 80-ых годов. В частности, борландовские компиляторы для х86 вместо инструкций деления использовали деление сдвигами.
Благодарю за такое обстоятельное дополнение!
это не баг, а именно фича. Технически NEG это "инвертировать все биты и добавить 1". А поскольку инверсные значения битов уже есть (у триггеров в регистрах есть и прямой, и инверсный выход), то NEG сводится к инструкции INC, применённой к инверсному выходу регистра аргумента.
NEG -- это изменение знака, а не инверсия, а инверсия -- это NOT:

Так что это не фича, а именно что баг (собственно, Интел где-то это признала, насколько помню).
не заменяет, но значительно ускоряет программную эмуляцию. Прям в разы. Скажем, сложение и вычитание это именно сдвиги — перед, собственно, целочисленным сложением мантисс их нужно выровнять друг относительно друга (чтобы совпадала "точка").
В разы ускоряется только операция выравнивания порядков перед сложением/вычитанием -- и то лишь если нужен очень длинный сдвиг, т. е. когда порядки отличаются очень значительно. Для умножения с делением выравнивание не требуется. А вот нормализация, которая может потребоваться после всех операций, требует предварительного определения положения крайнего левого единичного разряда -- а такой команды на тот момент не было, и его поиск сожрёт довольно много времени (ну или просто тупо сдвигать по одному биту, что при малом потребном числе сдвигов окажется даже быстрей). Ну и, естественно, само умножение-деление мантисс будет медленным, поскольку его придётся выполнять программно за отсутствием команд целочисленного умножения и деления.
В итоге, хотя операции и ускоряются по сравнению с процессорами, не способными сдвигать на много разрядов на один такт, но не так уж и сильно -- и в любом случае это намного медленнее, чем железный FPU.
И что самое смешное, barrel shifter позволяет реализовать целочисленное деление быстрее, чем его выполняли аппаратные делители 80-ых годов. В частности, борландовские компиляторы для х86 вместо инструкций деления использовали деление сдвигам
Неверное понимание. Деление (как и умножение) за счёт сдвигов выполняется быстрее лишь в одном случае -- если делить надо на степень двойки -- но тогда и без быстрого сдвигателя сдвиг окажется быстрей, если степень не очень большая. Если делить надо на константу, не являющуюся степенью двойки, то иногда можно ускорить операцию, заменив деление на умножение, сложение-вычитание и сдвиги -- современные компиляторы это делать умеют. А вот если делить надо на произвольную величину -- тогда всё, только полноценное деление, и быстрый сдвигатель в этом случае никак не поможет.
Софи Уилсон не участвовала в разработке, по той простой причине, что ее еще не существовало
За счёт чего у ARM низкое энергопотребление?
За счет простоты и вмешательства случая.
Первый ARM появился в эпоху 286‑х. Тогда у ARM было 27 тыс. транзисторов, у Intel — 134 тыс.
Инженеры ARM ориентировались на дешевый пластик для корпуса и отталкивались от задачи тепловыделения меньше ватта. Поскольку точно рассчитать выделяемое тепло в то время еще не могли, то создатели подстраховались и получили… 0,1 Вт — в 10 раз меньше. Сама Уилсон назвала это «чистой случайностью».
А у процессоров Apple? Чисто за счёт техпроцесса?
Болевая точка системы команд х86 - большой и сложный декодер, который работает всегда и по сути выполняет трансляцию сложных команд в микроинструкции (микрокод был начиная с первого 8086). В RISC-архитектурах, не только ARM, но и всех остальных, микрокода нет, т.к. сами инструкции простые. В итоге декодер на порядки проще, и, соответственно, имеет на порядки меньше транзисторов, которые жрут существенно меньше энергии.
Но зато x86+декодер позволяют ставить рекорды в однопоточных задачах?
Классическое микропрограммное управление никакого отношения к "трансляции сложных команд" не имеет, и декодирование у 8086 достаточно простое -- поскольку последовательное, байт за байтом, а не параллельное, да ещё для нескольких команд сразу, как в современных процессорах. На параллельное декодирование, учитывая бредовость интеловского кодирования команд, тогда банально не было ресурсов (транзисторов).
На этот вопрос наверняка бы лучше ответили @SIISII и @vanxant, которые выше в комментариях оставили экспертные дополнения.
Насколько я себе представляю, главные причины их низкого тепловыделения:
• очень плотный тех.процесс (3 и 5 нм);
• интеграция различных компонентов в одном чипе.
Сокращаются физические расстояния, которые надо преодолевать данным.
В 1980-е -- за счёт простоты процессора (грубо говоря, транзисторов меньше), что проистекало из примитивной системы команд (вдобавок, если сравнивать конкретно с Интелами, то у них система команд не особо-то эффективна -- в т.ч. из-за ужасного кодирования).
Сейчас -- из-за очень сложного декодера, о чём выше было сказано, но в сравнении есть определённое лукавство. Если будем сравнивать потребление энергии на выполнение какой-то элементарной команды (скажем, сложение), то при прочих равных у ARM оно будет сильно ниже. А вот если какое-нибудь шифрование нескольких килобайт данных... Современный AMD64/Intel 64 делает это, насколько помню, одной командой (IBMовские мэйнфреймы -- точно одно командой), на ARM же придётся шифровать программно, и кто меньше сожрёт в таких условиях -- уже большой вопрос, а если учесть ещё и потребное время на такую операцию...
Пы.Сы. А нанометры нынешние -- это маркетинг, к реальным размерам транзисторов они давно уже (где-то с рубежа 40 нм) отношения не имеют вообще.
Ага, спасибо! Про техпроцесс интересно, не знал. А что за нанометры тогда там теперь указывают?
История создания процессора ARM: от амбициозного проекта до сердца цифровой революции