Pull to refresh
48
0
Valentin Nechayev @netch80

Программист (backend/сети)

Send message

Ага, давайте сравнивать 68000 из 1979 с 80386 из 1985

Нет, ниже было в подробностях - сравнивать нужно диапазон 68010 - 68030.

Хотя вы можете сравнить и 8086 с 68000, конечно. 68000 на три года позже (реальные продажи - 1981), так что к IBM PC он катастрофически опоздал.

То есть выяснили, что страничное MMU в 68k появилось за 3 года до 386.

А в S/370 оно появилось на ≈10 лет раньше, и что?
А сколько стоило то MMU, вы таки посмотрели? Ещё удвоить цену процессора? Соответственно, сильное сокращение рынка. Аналогичный пример был с 8087, пока в 386-е не начали вкладывать FPU блок - его ставили только в специализированные машины.

А давайте ещё регистры посчитаем. 8 штук D и 7 штук (не считая стека) A. А в х86 ВСЕГО 7 регистров. Или это не считается?

С количеством регистров - я безусловно согласен, их в 2 раза больше (или 2.5, как считать). Вопрос в том, насколько это влияло на удобство работы кода - в те-то времена. Когда разрабатывалась PDP-11, например, в ней не захотели делать больше 8 регистров, потому что люди путались в таком количестве. Компиляторы стали заметно продвинутее только где-то с середины 1990х, потому что начала разрабатываться теория в современном виде, до этого они были совершенно топорными. Это требует серьёзного рассмотрения, была ли польза с тех 16 (15, неважно).

А вот то, что сейчас ностальгически вспоминается то, чего не было - якобы полная ортогональность - это факт бесспорный.

Тогда становится неясно зачем амд добавило r8..r15 регистры, наверное дураки были

Когда именно AMD их добавила? Это было на 10 лет позже. Для индустрии в те времена это чудовищный промежуток, поменялось практически всё. Про компиляторы я уже говорил, см. выше. Уже набрался опыт и с RISC-процессорами сразу нескольких архитектур, и SSA начали вводить. А вот на 1979 такое было критически мало где, я с ходу только S/370 вспомнил.

Насколько я помню, в 68060 команды не могли продолжаться, только заново переисполняться. Ну и в x86 можно найти ужасы, типа rep movsb. И ничего -- живут как-то, на "микрокоде" дешифруют и исполняют. Так что это плохой аргумент -- технические проблемы вполне решаемые для OoO.

То, что я говорю, это не техническая проблема, после того, как зафиксировали то, чего фиксировать не надо было.

68060 вышел в 1994, это уже был закат. Тут надо уточнить историю, возможно, они ввели несовместимое изменение, но уже опоздали. Факт то, что мозговой заклин на супер-CISC, когда его времена давно ушли, мог - и скорее всего он в первую очередь и погубил - не только m68k, но и другие архитектуры той разработки - в первую очередь VAX.

А вы сколько килобайт кода собственноручно написали для 68к?

Мало. Считайте, один. Но на объективность это не влияет. У меня нет никакой повышенной любви к архитектуре x86 - можете погуглить, какими словами я её ругаю. Но то, что из-за меньшего количества CISC-like наворотов она оказалась более подготовленной к повороту в сторону OoO и RISC - чисто объективный факт, не признавать его нельзя.

или, в ООП-стиле:

Это не ООП-стиль, а процедурный (он же императивный). ООП ортогонально императивности или функциональности.

Я предпочитаю называть два основных стиля ООП - "активные объекты" и "пассивные объекты". В случае Simula/etc. имеем первый. В случае C++, Java, C#, тысячи их - второй. Да, они разные.

В Эрланге же у вас появляется класс gen-Server, который из которого создается процесс (объект).

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

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

Извините, это или злая и неумная шутка, или вы совершенно не владеете проблемным доменом.

И к теме, как писать - a+b или a.plus(b), это имеет отношение только в контексте такой же древней явы, но никак не ООП в целом.

Может и при выполнении. Но тут начинает сильно зависеть от языка, компилятора и прочего.

Простейший пример - если вы записали c=a*b, где все участники - матрицы, вполне возможно, что при размерах матриц миллион на миллион среда сама раскинет это на 100 компов в кластере. А вам не надо было писать все итерирования строк-столбцов, вы просто попросили результат - произведение матриц.

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

Единственный объективный минус ООП это его низкая производительность. Например, инструкция x = a + b в десятки раз быстрее чем x = a.plus(b)

Чтобы было в десятки раз, надо делать динамическую диспетчеризацию в рантайме, по имени метода. А зачем весь ООП сводить к этому?

В C++, например, a+b внутренне превращается в a.operator+(b) или operator+(a,b), где operator+ - такое имя функции, аналогичное вашему plus. А дальше выполняется обычный себе код соответствующей операции (например, для complex это два примитивных сложения, для real и imag части).

Так что "десятки раз" - сказки, и, хм, интересно их происхождение. Поделитесь.

Все остальное от неумение его готовить, но тут как говорится "просто у тебя нормального мужика не было".

Что ООП не всегда уместно - факт. Но его хаятели очень преувеличивают недостатки.

Там было "примерно 100 долларов. Так что 640kB было какой-то несбыточной цифрой на те времена (4100 долларов..."

Кажется, форматтер символы доллара понял как ограничители формулы.

Имхо, достаточно было бы в Си добавить средства, облегчающие организацию VMT, и на этом стоило бы закончить.

VMT - раз.
private - два (надо же защищать от внешнего неавторизованного доступа).
namespaces - три (есть тут у меня один компонент, названия типа rrx_sub_trr_pkt_new задалбывают).

Вот уже именно что языковые средства и 1/5...1/4 от C++ уже есть.

И что странного в зашивке в язык, если там всё равно уже зашито 100500 всего начиная с типов, а это конкретно - используется очень значительной частью софта?

Ну я только по Киеву могу показать: улицу, где несколько километров исторически вырезаны (а сейчас частично восстанавливают); улицу, которая формально так пересекается с собой несколько раз (а реально там промзона, в которой было всем плевать, что за улица, знали объекты) и тоже порвана на части; две улицы с двумя рукавами (одна тоже в промзоне, вторая в частном секторе); одинаковые названия в разных частях города, так что требуется уточнение районом.

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

[​​1. С семейством m68k надо сравнивать 80386 и далее, а не 8086. Защита памяти появилась в 80286, но не страничная. В линии m68k она появилась не в 68000, а в 68010, а это уже 1982 - то есть он ровесник 80286; но у 68010 это требовало внешнего MMU, решение было не из дешёвых (тогда). 68020 аналогично требовал внешнего MMU. Только с 68030 они смогли впихнуть MMU внутрь, а это уже 1987, через два года после 80386.

​2. Неортогональность по регистрам в 32-битном режиме x86 значительно снижена - именно там, где она била больше всего (режимы адресации). То, что она остаётся и сейчас в вариантах типа косое умножение с результатом в xDX:xAX, переменный сдвиг в CL - ни на что реально не влияет.

​3. У m68k нет полной ортогональности по регистрам. Например, можно добавить содержимое D-регистра к памяти, но нельзя то же самое для A-регистра. К A-регистру нельзя добавить произвольную константу. ADDx (аналог ADC) не работает на A-регистрах. То же про битовые операции. Однобитовые операции типа BFCHG не разрешены почему-то для режимов типа (An)+. Когда вы говорите

ортогональная к регистрам, очень логичная система команд

вы почему-то игнорируете все эти тонкости и нелогичности.

​4. Зато есть безумные двойные косвенные режимы типа ([bd,An],Xn,od). Именно они убили всю архитектуру: перевести их на out-of-order исполнение оказалось просто невозможно, причём не технически, а административно: кто-то постановил, как именно в каком порядке они проходятся, для возможности восстановления с любой промежуточной точки. X86 как более примитивный таки избежал этого.

Мне, конечно, нравятся некоторые аспекты m68k, но именно из-за описанного в конце не считаю её настолько лучшей. Мнение типа "m68k была заведомо лучше x86" - это чистый туман размытых воспоминаний, подкрепляемый фанатичными ненавистниками x86. Я пытаюсь быть объективным:)

Тут следует упомянуть, что самые первые IBM PC могли поставляться вообще с 16KB памяти, и на 1981-й это ещё стоило примерно 100. Так что 640KB было какой-то несбыточной цифрой на те времена (4100, на персональный компьютер - нереально). А на потом думали вообще сменить архитектуру. Проблема в том, что, условно, MS-DOS задержался на десять лет по сравнению с тем, что ожидали (в заметной мере, в своих наполеоновских планах) авторы железа, программ, журналисты и прочие, и, несмотря на то, что адресация далее 1MB была уже в 80286, массовое переписывание кода на новый стиль стало быть позволено уже только в середине 1990-х. Вот об этом бы почитать подробнее, каким образом и почему индустрия впала в такой заклин.

микропроцессоры Motorola были лучше, чем интелловские

В плане адресации - да. В остальном - нет. Когда пришла возможность делать out-of-order исполнение, для десктопных процессоров это начало 1990-х, линия m68k умерла потому, что была over-CISC в массе деталей, как именно исполняется команда, какое количество и сложность режимов адресации, и введя эти детали в спецификации своего ISA. А у x86 такого ограничения не было. По тому, например, что в командах (кроме строковых и всяких служебных) не более одного операнда в памяти, она оказалась ближе к требуемому в новые времена (RISC) и потому выжила. Конечно, правительство этому помогло (см. историю про ASCI Red), но это лишь ускорило на несколько лет неизбежную смерть m68k. А у x86 к тому времени был отлаженный 32-разрядный режим.

(Кстати, почему только 16MB? Адрес 32-разрядный, значит, наступал период обновления. Немного раньше S/370 прошла этот путь, 370/XA расширило адрес с 24 до 31 бита. И там было много граблей в первую очередь с софтом, пришлось добавлять режим 24-битной адресации для старого пользовательского кода, а ядерный пришлось массово переписывать, где он зависел.)

fizzbuzz нельзя использовать на собеседовании как быстрый косвенный способ оценить практические навыки.

Можно - в режиме live coding. Но это потребует более высокого уровня интервьеров.

Темы про ООП мне кажутся как темы плоскоземельщиков.

В смысле, отрицатели ООП - плоскоземельщики? Полностью согласен 😆

Но если вам так нравятся мыслительные упражнения

Давайте без таких излишне полемических приёмов.

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

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

Но я могу вам задать вопрос с ещё более крутым подвохом: если взять процедурный код, в котором нет ни одного класса, и все его функции сделать статическими методами классов. Будет ли это ООП?

Я считаю, что нет, и нет разницы с моим вопросом. Классы тут будут играть роль пространств имён. Но это может быть предварительным шагом перед созданием уже реально ООП кода.

А потом улицу решили продлить, от "начала улицы" дальше построили еще несколько домов. Какие им номера давать? Отрицательные?

А вы что предлагаете? Давать им случайные незанятые номера, чтобы окончательно потом все запутывались?

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

А еще бывает топографический объект "Площадь". У нее от центра расстояния до домов могут быть одинаковы, поэтому нужно учитывать угол. Здесь явно номера напрашиваются комплексные.

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

Если код сам по себе полностью процедурный без единого класса, но использует библиотеку, в которой создаются объекты и зовутся их методы - это считать ООП?

ООП не нужен: смотри на Linux

Смешно тут то, что авторы таких утверждений не понимают (или не хотят признавать), что Linux, и ядро любого Unix, и ядро Windows - они все на ООП как раз классического пассивного, не-Кеевского типа. Полиморфизм на виртуальных функциях - в полный рост. Уровень сисколлов: есть универсальный read() на всех, write(), close(), fcntl(), вплоть до epoll и io_uring, ко всем применяются одинаковые методы для большинства работ, внутри происходит переключение. В реализации read(), например, ret = file->f_op->read_iter(&kiocb, &iter); - f_op это Virtual Method Table.

Инкапсуляция делается только на границе user land / kernel land, да. Но это ограничение языка. Был бы даже очень урезанный C++ - всякие private и protected были бы везде. А пока следят на уровне верификации кода (начиная с визуальной).

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

Так что вы с этим

Конечно, в ядре Linux не до полиморфизма

неправы, Linux ещё больше играет за вашу же команду: ООП нужен - там, где удобен.

(Повторюсь) сокращение - не проблема. Ну стали нумероваться с 81 вместо 1, зато принцип расстояний соблюдается, вместе с монотонным возрастанием номеров в ходе движения. А не так, что, например, идут 3,5,7,9, а потом вдруг 3а.

Information

Rating
7,264-th
Location
Киев, Киевская обл., Украина
Date of birth
Registered
Activity