Как стать автором
Обновить
45
0.7
Иван Савватеев @SIISII

Микроконтроллеры, цифровая электроника, ОС…

Отправить сообщение

Ну, у VHDL нет полноценного аналога интерфейсам из SystemVerilog (во всяком случае, нет в тех версиях, которые реально доступны в средствах синтеза; в самом последнем стандарте, может, и ввели, но поддерживать его начнут хз когда). Плюс громоздкий, да, но реально меня в нём бесят в этом плане только to/downto. Так что, в общем и целом, я предпочитаю SV, но если выбирать между просто Верилогом и VHDL, выберу последний.

Ну, под Виндой никаких проблем с Хилинхом у меня никогда не было. Но для линухоида, понятно, будет удобней в привычной системе.

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

В защищённом, конечно. Реальный -- пережиток прошлого.

Разве select и poll -- это асинхронный ввод-вывод, а не неблокирующий? Я не линухоид, поэтому и спрашиваю. Просто неблокирующий к асинхронщине отношения не имеет и толку с него в этом плане примерно нуль (смысл асинхронного ввода-вывода, как правильно указано в статье, -- сообщать о завершении операции ввода-вывода, ну а неблокирующий лишь говорит о том, что файл готов к дальнейшей работе -- а, скажем, настоящий честный дисковый файл всегда готов).

Он никогда корректен не был. Скажем, Система 360 была анонсирована в 1964-м, первые модели поступили в продажу в 1965-м -- и её 16 регистров общего назначения были таки "общего назначения". Правда, в трёх экзотических командах использовался один жёстко определённый регистр (в Системе 370 число таких команд возросло до шести), но подавляющее большинство команд, в том числе все "нормальные", используют регистры на равноправной основе. Про PDP-11 выше тоже сказали; правда, указатель стека и счётчик команд относятся и адресуются как регистры общего назначения, хотя таковыми, по сути, не являются -- но то же самое относится и к ARM, например.

В общем, сей "признак" характерен либо для 8-разрядных микропроцессоров, либо для исключительно уродской системы команд 16-разрядного 8086/8088, но не для других современных последнему 16-разрядных микропроцессоров, например, Zilog Z8000.

Безусловно. Ни первой конвейерной, ни первой суперскалярной S/360 не была; вот внеочередное выполнение команд, кажется, впервые реализовали таки на одной из моделей этого семейства в самом конце 1960-х. Но, возможно, IBM стала первой, кто все эти вещи стал внедрять в относительно массовых вычислительных системах, а не в единичных исследовательских проектах или супер-ЭВМ.

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

В V86 он войти не может, насколько помню: поддержка V86 выпилена из 64-разрядного режима. Хотя за IA-32/AMD64 уже много лет не наблюдаю, так что могу и ошибаться.

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

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

Нет, основной код -- как раз на сях; на питоне -- вспомогательный скрипт, без которого можно обойтись.

Но настоящая проблема не в том, что молодёжь питон использует, а в... скажем так, узколобо-фанатичном подходе и в крайне узком кругозоре, характерном для очень многих. Тот же ИИ отнюдь не на питоне сделан, вся лежащая в его основе математика написана на других языках, вплоть до фортрана и ассемблера. Но из всех утюгов несётся: питон, питон, питон! (А 10 лет назад неслось: руби, руби, руби!)

Ну, хоть кто-то в 16 лет сейчас интересуется ассемблером и прочими низкоуровневыми вещами, а не сплошными быдлосайтиками или, в лучшем случае, ИИ на пыхтоне :)

Из минусов -- приличное кол-во ошибок в русском языке. Стоило б подтянуть.

Целый ряд неточностей, да и выводы сомнительны. Пройдусь по некоторым вещам.

Для начала -- о терминологии CISC и RISC -- это не архитектуры, это, если угодно, способы организации архитектур, но не сами архитектуры. И IA-32 (x86), и System/360, и PDP-11, и VAX-11 -- это всё CISCи, но совершенно разные, т.е. разные архитектуры. То же самое касается и RISCов.

Придерусь и к ISA, т.е. к instruction set architecture. Это -- не очень удачное определение, так как затрагивает только одну сторону вопроса, ведь архитектура -- это не только набор команд. Архитектура определяет и ряд других вещей, например, способы обработки прерываний. Можно, скажем, взять систему команд от VAX-11, но прицепить к ней обработку прерываний от M-профиля архитектуры ARM -- и что тогда получится? Это ведь будет уже и не VAX, и не ARM.

Насчёт конвейеризации. CISC, в общем и целом, на конвейер ложится ничуть не хуже RISCа. В частности, среди первых моделей Системы 360 старшая была уже конвейерной; из первых четырёх ЕС ЭВМ, которые архитектурно тоже были Системой 360, старшая -- ЕС-1050 -- была конвейерной, ну и т.д. Более того, в 1960-х появились и первые суперскалярные процессоры, и даже процессоры с внеочередным (out-of-order) выполнением команд. Просто тогда это был удел буквально нескольких машин во всём мире, а сейчас такое чуть ли не в каждом утюге встречается -- но это является следствием развития микроэлектроники.

Далее, начсёт частоты использования команд и их влияния на производительность. Да, простые команды используются намного чаще, и это было неправильно воспринято некоторыми как возможность "безнаказанно" избавиться от сложных команд. Результатом стал, в частности, MIPS. На сравнительно небольшом промежутке времени -- в 1980-90-х -- это, действительно, позволило добиться превосходства в производительности над вычислительными системами аналогичных массо-габаритных характеристик и себестоимости, но причина крылась в другом: тогдашние технологии уже позволяли впихнуть простой процессор в одну микросхему, но не позволяли сделать этого для сложного процессора (или позволяли, но только с чисто микропрограммным управлением, без конвейера или с очень простым конвейером). Соответственно, MIPS, будучи выполнен в виде одной микросхемы, мог работать на высокой тактовой частоте и при этом реализовывать конвейерное выполнение команд, а какой-нибудь 80386 -- не мог. Вот топовый мэйнфрейм рвал по производительности и 80386, и MIPS, как тузик грелку -- только его не поставить было не только на стол, но даже и в небольшую комнату.

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

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

По этим причинам в современных RISCах от изначальной идеологии RISC мало что осталось. Скажем, современные ARMы сохранили лишь невозможность прямой обработки данных в памяти -- их требуется загружать для этого в регистры. Однако у них переменная длина кода команды, переменное время выполнения команды, а сам полный набор команд насчитывает не одну сотню (для сравнения: у Системы 360 полный набор включал всего лишь 143 команды). В общем, в нынешнем ARMе наличествуют почти все черты типичного CISCа. Конечно, кодирование команд в ARM многократно проще, чем в IA-32 (x86), но последняя -- пример того, какой не должна быть система команд, а особенно -- её кодирование; она отвратительна со всех точек зрения. А вот команды Системы 360 или, скажем, PDP-11 декодировать ничуть не сложней, чем команды ARM, -- хотя они являются самыми что ни на есть настоящими CISCами.

Ну и насчёт сложности процессоров. Процессор какой-нибудь ЕС-1020 или System/360 model 30 ощутимо проще, чем даже жутко примитивное ядро Cortex-M3 M-профиля архитектуры ARM, не говоря уже о всяких там Core i-100500. Основную сложность создаёт не система команд как таковая и даже не конвейер, а реализация суперскалярного и особенно внеочередного выполнения команд. Дурное кодирование команд в IA-32 резко усложняет задачу их декодирования (попробуй, хотя бы, определи длину команды!), но после декодирования, по большому счёту, особых сложностей с выполнением команд нет. Ну и ничто не мешает реализовывать простые команды чисто аппаратным управлением, а сложные -- аппаратно-микропрограммным: какое-нибудь микропрограммное шифрование будет выполняться всяко быстрее, чем тот же самый алгоритм, реализованный чисто программными средствами, а дополнительных аппаратных затрат требует мизер.

Когда как. Скажем, если благодаря ручному написанию на ассемблере удастся уместиться в одну строку кэша, скорость иногда может возрасти в десятки раз -- хотя это патологический случай, конечно, но полностью исключать подобное было бы неправильно. Про зависимости по данными Вы сами написали. Плюс, программист, в отличие от компилятора, знает, что и когда действительно нужно; когда можно забить на "волатильность" данных, а когда нет, ну и т.д. -- а это может избавить от кучи лишних телодвижений. Понятно, что для ПК это почти всегда некритично, а вот на микроконтроллерах может иногда быть важным.

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

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

Если изучил один асм, перейти на другой будет весьма и весьма просто.

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

На самом деле, UB тоже может иметь место :) В частности, насколько помню, команды сдвига в 8086 в некоторых случаях не совсем так же работают, как в более поздних процах (но только в экстремальных случаях -- скажем, когда счётчик числа сдвигов превосходит разрядность; но подробности за давностью лет не помню). Но по сравнению с сишным UB... :)

Интересно, с чего это высокий порог входа? Он весьма и весьма прост. Разве что многословен -- это да.

Информация

В рейтинге
1 671-й
Откуда
Солнечногорск, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Embedded Software Engineer
Lead