Комментарии 66
В статье описывается, что CISC хорош для высокой производительности, а ARM для снижения энергопотребления. Для меня такое противопоставление не понятно. Есть характеристика производительность на ватт подводимой мощности. ARM тут выигывает. То есть, делаем два мощных процессора, которые потребляют одинаково, по максимому, сколько может рассеивать один процессор. ARM получится мощнее, чем x86.
В моем понимании железа, RISC превосходит CISC. Единственная причина, по который мы не на ARM или другом RISC - это совместимость со старым ПО. Просто тащим этот груз, который выкинуть бы давно пора. А в статье пишется, что вроде как есть другие причины, но я не нашел ни одной. Пишется, что x86 лучше для высокой производительности. Но чем лучше? Может, хотя бы в одном потоке он обгоняет ARM при сопостовимой потребляемой мощности? Или есть ограничения на максимальную мощность ARM? Может, я что-то упускаю?
Тема не раскрыта.
Большая часть отличий в производительности вообще и производительности на ватт определяется не архитектурой, а микроархитектурой. Разве что более сложный декодер x86 влияет на энергопотребление и в мобильном сегменте это заметно. А в плане пригодности ARM для высокой производительности - см. последние чипы от Apple и номер 4 в Top 500.
Главный недостаток RISC - это больший размер исполняемого кода, чем у CISC. Это приводит к большей потребности в чтении из памяти, а память намного медленнее процессора, даже если это кэш-память не самого первого уровня. Выходом здесь может быть увеличение ширины шины памяти, её скорости и количества каналов за счёт многоэтажной конструкции чипов с вертикальными связями, как в процессорах Apple M. Но пока такая конструкция плохо масштабируется и не имеет никаких возможностей для апгрейда.
больший размер исполняемого кода, чем у CISC
Всё не так однозначно - вот тут есть сравнение с цифрами.
Тоесть в итоге получаем, "теоретический CISC лучше, ибо по-сути представляет из себя сжатый набор команд закодированный по частоте использования"
На практике у нас есть только х86, который уже давно перестал быть оптимальным решением
У меня вывод, что лучше RISC. Длинна кода для RISC не возрастает (выше пруфы). Сам кристалл вроде бы проще, но это не точно. Все остальное одинаково. Но для RISC компилятор собирает код из более мелких кусочков, чем для CISC и у него больше возможностей для оптимизации.
У компилятора для RISC обычно действительно больше возможностей для оптимизации, но по другой причине. В CISC есть все команды, которые есть в RISC, так что никто не запрещает компилятору применить те же возможности оптимизации. С CISC хуже другое - для одной системы команд разные процессоры имеют существенно разный по алгоритму микрокод с существенно разными задействованными для каждой конкретной команды ресурсами, поэтому для наилучшей оптимизации компилятору теоретически нужно знать конкретную модель процессора. На практике это обычно неприменимо, кроме, разве что компиляции ядра Linux под конкретный процессор. А для RISC вариантов использования ресурсов процессора гораздо меньше, и универсально оптимизировать код намного проще.
В целом это справедливо и для RISC. У них всё тот же микрокод. Просто там не так много выбора как именно сделать одно действие. У того же х86 просто загрузить данные в регистр можно кучей разных способов, кода у RISC на это всего одна-две команды.
Раньше развлекаясь нашёл забавную вещь. В х86 можно написать банальный for(i) цикл используя 2 байтную команду, но компилятор не использовал её ибо на целевом интуле это команда работала условно 40 тактов, а вот последовательность из +5 команд всего в 3 такта. (некоторые команды могут объединятся на конвейере)
У них всё тот же микрокод
Надеюсь, вы имеете в виду разбиение инструкции на микроинструкции. Микрокод в том смысле, который использовал Паттерсон в классической статье, и на x86 сейчас применяется только в специфических случаях.
Раньше развлекаясь нашёл забавную вещь.
Достаточно частый случай - скажем, вместо ENTER/LEAVE генерируется стандартная последовательность с push/pop rpb. Как то надо было для тестов получить код с CMOV - тоже обнаружил, что при оптимизации под более-менее новые интеловские процессоры компилятор её не выдаёт, простой код с условным переходом быстрее.
Кроме этого теоретического преимущества у CISC также есть существенные недостатки в виде сложного декодера, вместо которого в некоторых случаях можно было бы поставить второе ядро на той же площади кристалла, и более длинного конвейера, который вынуждает использовать более сложный предсказатель ветвлений, и при этом всё равно больше теряет из-за его ошибочных предсказаний. Ну а у современной версии х86, судя по приведенным здесь результатам измерений, и этого преимущества не осталось, потому что его система команд уж слишком отягощена обратной совместимостью.
Я в курсе как устроен CPU, писал свои процессоры на досуге.
В целом проблема CISC буквально только в декодере. Если мы берём традиционное представление CISC где команда может иметь переменное количество байт на команду, то выходит что мы просто физически не можем увеличить подачу инструкций на конвейер. Тоесть ограничены условными 3-4 командами на такт. Спасает то что эти команды обычно комплексные и позволяют закодировать 1-4 действия в одну команду, потому отставание не кажется таким уж существенным. Можно строить всякие эвристические декодеры, которые бы просто наугад кэшировали мопы для участков кода, но это буквально костыли)
В итоге потенциальный потолок у RISC архитектур выше, декодеры можно тупо в ряд делать получая свыше 8 инструкций на такт. Но всё же переменное кодирование инструкций очень полезная вещь, в современных RISC есть всякие флаги/режимы позволяющие менять размер команды на кратное двойке значение. Эдакий CISC на минималках. Что в целом является отличным компромисом между этими двумя типами архитектур.
Тоесть получаем CISC с командами переменной длины = зло, а CISC/RISC с командами перемнной длины кратные двойке = спасение. Почему кратные двойки? Вместо оценки длины команды и определения какому декодеры скармливать команду, мы можем тупо сделать матрицу из 16/32/64 битных декодеров и не получать издержек на определение длинн, как в традиционных CISC. В итоге на одном теоритическом декодере можно получить от 4 до 16 инструкций на такт, сильно да?
Как всегда, правда где-то посередине
Кроме прочего переменный размер инструкции - ни разу не отличительная особенность CISC. Скажем, в RISC V есть расширение для использования 2байтных инструкций вперемешку с "обычными" 4байтными.
На практике уже давно не х86, а амд64. Х86 есть в кристалле, но давно не используется.
БОльший размер исполняемого кода влияет только на одно - на количество instruction cache misses. Это иногда может сыграть заметную роль по перфу, но найти такой тест, чтобы это стало заметно в части ARM vs X86 надо ещё постараться. И это точно не станет никогда узким местом в части обращения непосредственно в память и требованиям к канальности памяти. Несколько мегабайт (или даже десятки ) LLC кэша вполне гарантируют вам попадание всего кода в кэш.
Большой LLC кэш может гарантировать попадание всего кода в кэш только в том случае, если ядер мало, или они все выполняют один и тот же код. А в ARM-процессорах, которые претендуют на замену мощных X86, ядер больше сотни, так позволяет сделать низкое энергопотребление ядер, но если все они будут выполнять различный код - LLC кэша вполне может не хватить для кода.
В общем, это придуманная проблема. Никогда скорость и канальность памяти не проектируется исходя из вопроса размера кода, главное там - это объём обмена данными и работы подсистемы кэша данных. В принципе, если у вас из L1I код начинает часто выпадать, это уже криминал. Размер кода инструкций имел важное значение на заре проектирования микропроцессоров, также определённую важность он имеет сейчас при проектировании микроконтроллеров. А для соврменных серверных/десктопных процессоров разница в размере кода между CISC/RISC не влияет почти ни на что. Скорее более сложный декодер для CISC имеет значение, хотя впрочем тоже небольшое
В принципе, если у вас из L1I код начинает часто выпадать, это уже криминал.
Что такое часто? К примеру, размер кэша L1 процессора AMD Ryzen 7 8700 - 512 кбайт, а задержка при обращении к L2 - 3 нс, что при частоте 5,1ГГц составляет 15 тактов.
В принципе, если у вас из L1I код начинает часто выпадать, это уже криминал.
На энтерпрайз приложениях (базы данных, всяческие Spark/Hadoop и т.п.) обычное дело, когда большая часть обращений к L2 инициируется L1I миссами. И iTLB миссы тоже существенно влияют на производительность. Но, как писал выше, разница в размере кода на CISC и RISC - скорее миф, чем реальность, надо сравнивать конкретный код на конкретных архитектурах.
Но чем лучше? Может, хотя бы в одном потоке он обгоняет ARM при сопостовимой потребляемой мощности? Или есть ограничения на максимальную мощность ARM? Может, я что-то упускаю?
Но еще x86-процессоры, как Intel Core i9-13900K, превосходят ARM в однопоточных задачах благодаря более высокой частоте и IPC, достигая 30 000 баллов в Geekbench 5 по сравнению с 1 700 баллами у Apple M1. При сопоставимой мощности x86 обычно предлагает лучшую производительность на такт, но ARM-процессоры показывают лучшую производительность на ватт (1.5-2.0 производительности на ватт). ARM-процессоры, хотя и улучшаются, традиционно имеют ограничения в максимальной мощности по сравнению с высокопроизводительными x86-процессорами.
А кто или что ограничивает ARM-процессоры в максимальной мощности? Если сделать два процессора с одинаковой потребляемой мощностью ARM и x86, то ARM будет производительнее, так?
И что мешает частоту для ARM увеличить?
то ARM будет производительнее, так?
Нет, не так. Это так не работает, производительность не масштабируется однозначно с потребляемой мощностью ни вверх, ни вниз. Можно сравнивать только реально существующие процессоры. А ответ на вопрос "что мешает увеличить частоту" может быть очень разным, от "не впишемся в термопакет" для мобильных устройств до "не получается" для серверных.
Речь не про мобильные устройства, и "не впишимся в термопакет" не аргумент. "Не получается для серверных" - почему?
Я хочу понять - существуют ли реальные причины не использовать ARM для высокопроизводительных систем - серверов, десктопов, рабочих станций. Пока никто не назвал мне ни одной реальной причины. Поэтому, у меня складывается впечатление, что причина только одна - совместимость, традиция. Получается это просто тормозит прогресс, и все.
Что мешает погуглить характеристики серверных процессоров ARM?
"Каждое ядро современных высокопроизводительных процессоров для настольных ПК, таких как Intel® Core® i7 6700"
Дальше читать не стал...
А что делает приведенный ассемблерный код для ARM?
Где вы в статье ARM ассемблер нашли? Я вижу псевдокод, иллюстрирующий разницу между гипотетическими CISC и RISC.
Ок, псевдокод.
Пытались показать одно и тоже действие на разных процессорах, но что-то пошло не так!
Могут, конечно, сказать, что так в источнике, но зачем копировать ошибки?
Вот как можно охарактеризовать наборы команд для ARM.
...
Гарвардская архитектура. RISC обычно использует гарвардскую модель памяти, которая разделяет пути хранения и передачи сигналов для инструкций и данных, что еще больше повышает эффективность обработки
Давно ли в ARM общего применения, которые рассматриваются в статье, гарвардскую архитектуру реализовали?
насколько я знаю в относительно свежих процессорах, таких как ARM Cortex-X2 и Neoverse V1, применяется гарвардская архитектура с раздельными кэшами для инструкций и данных. Некое продолжение традиции, начавшейся с архитектуры ARMv6 2002 года)
архитектура с раздельными кэшами для инструкций и данных
Используется на интеловских процессорах начиная по крайней мере с Pentium Pro (1995 год). В каком то смысле это элемент гарвардской архитектуры, но всё таки адресное пространство для инструкций и данных общее и снаружи они поступают в процессор через одну и ту же шину или контроллер памяти.
Кэш на всех процах разделяется. И в ядрах GPU, и даже в микроконтроллерах Cortex-M0 за $1.
UPD: Микро-архитектура с кэшем у всех получается гарвардской. Но я что-то я не замечал, что разработчики ставят один чип или планку памяти отдельно для данных, а второй - отдельно для программ. Чисто гарвардская - это разве что AVR/Ардуино и PIC.
Вот как можно охарактеризовать наборы команд для ARM...
...
Большое количество регистров. Чтобы минимизировать необходимость в более медленном доступе к памяти, RISC-системы используют большое количество регистров. Это позволяет командам работать непосредственно с данными, хранящимися в регистрах, а не обращаться к памяти часто.
ARM и x64 имеют практически одинаковое количество регистров.
Т.е. в целом, архитектуры RISC и CISC действительно имеют такие свойства, но в статье рассматриваются конкретные семейства.
Абсолютно безграмотная статья. Тот редкий случай, когда неправильно почти всё. Наверное, можно написать отдельную статью, чтобы указать все косяки. Самое главное, абсолютно некорректен посыл, что от архитектуры RISC/CISC как-то существенно зависит производительность или энергопотребление. От архитектуры это сейчас практически не зависит никак, всё определяется микроархитектурой чипа, применяемым техпроцессом, качеством физдизайна и набором других параметров, никак с системой команд не связанными.
Господа,
Предлагаю коллективно создать реестр для сравнения процессорных ядер
https://docs.google.com/spreadsheets/d/1y9DpZ5n3_t8Bk6t6CaU0f8WBJGfK05y20dzH8ncdMrs/edit?usp=drivesdk
Это поможет нам лучше понимать ход развития истории в этой предметной область и находить ближайшие аналоги, прослеживать эволюцию. Делать аналитику.
Было бы здорово, если каждый напишет про тот проц с которым упорно работал.
Кто готов пополнить реестр я добавлю возможность редактировать.
Делать аналитику.
для чего?
https://en.wikipedia.org/wiki/List_of_ARM_processors
Тут мало инфы и нет даже базовых характеристик.
И это только армы. А есть ещё power pc, risс v и прочие ядра
wikichip.org не поможет?
Этот сайт даже про ARM Cortex-M4 ничего не знает...
Эм, Селектел, вас-то кто укусил? Вроде обычно достаточно вменяемые статьи, а тут прям какой-то поток бессознательного бреда. Новую сетку для написания шлака на хабр тестируете? Мож не надо, их тут и так уже .. изрядно больше чем хотелось бы
Просто лень перечислять, плохо буквально всё..
В 2000 году время доступа к памяти DRAM составляло около 100 наносекунд, а в 2020 — уже более 200
Память за 20 лет стала медленее?
Увеличилась эффективная задержка, это не только физическое время доступа, но и задержки, связанные с архитектурными особенностями, а как раз абсолютное время доступа к ячейкам DRAM фактически уменьшилось.
Что такое "эффективная задержка"? Вот у меня i5-13600KF с DDR4, латентность в тесте памяти AIDA чуть меньше 100нс . Это эффективная задержка, или не очень, и как мне получить те 200 из вашего текста?
тест AIDA дает чуть меньше 100 нс это относиться к физической задержке доступа к памяти. Если мы говорим об эффективной задержке, то учитывайте дополнительные системные задержки, такие как время доступа к кэшу и задержки шины, которые могут добавить примерно 100 нс. Так что, эффективная задержка может составлять около 200 .
тест AIDA дает чуть меньше 100 нс это относиться к физической задержке доступа к памяти.
Нет. "Физическая задержка" (если под ней понимать CAS latency, время от поступления чипу сигнала "давай данные" до возвращения им данных из столбца) там порядка 15нс.
то учитывайте дополнительные системные задержки, такие как время доступа к кэшу и задержки шины
К какому кэшу? У любого процессорного кэша задержки МЕНЬШЕ, чем у самой памяти. И что это за "задержки шины", которые тест не показывает? Он как-то мимо шины читает данные? Если да, то как?
И вопрос "как получить 200нс" все еще открыт (как получить 100нс в 2000, я примерно знаю :)). Их можно каким-то широко распространенным ПО увидеть? Вы же опирались на какие-то реальные данные, когда про 100 и 200нс писали, правда ведь? :)
Уже лет 15 как время случайного доступа к памяти держится в районе 40-60 нс. Сложите 3 тайминга памяти,типа 22+24+22, разделите на её тактовую частоту (половину скорости DDR), и получите это самое время.
А время последовательного доступа в линейке DDR2,3,4,5 таки уменьшается за счёт большей параллельности, буферизации и скорости самого интерфейса. Софтописатели и компиляторы это учитывают.
Статья - копирайтерский мусор из 2015 года.
"Этот подход к проектированию подчеркивает простоту и содержит меньше инструкций, которые могут быть выполнены за один такт. Это обеспечивает эффективное декодирование и выполнение, что приводит к повышению производительности за такт и снижению энергопотребления."
Меньше инструкций выполняется за такт, но производительность за такт выше ?
Сравнение ARM и x86: от структуры чипов до применения