ФЭНДОМ


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

Все началось в 1971-ом году, когда в исследовательскую лабораторию Xerox Palo Alto (Xerox PARC) пришел Alan Kay. Именно это человек впервые употребил термин object-oriented.

В лаборатории он возглавил проект по разработке пользовательского интерфейса, основанного на графических пиктограммах, а не на командной строке.

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

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

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

В языке Smalltalk, основной конструкцией является конструкция посылки сообщения. Язык является динамически типизированным, это означает, что в объявлениях не содержится указание типов. Все данные являются частными, а все методы публичными. Простейшие типы данных: число, строка, множество - являются полноправными объектами, для которых можно определять методы точно так же, как и для любых других объектов.

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

Справедливости ради, стоит отметить, что Smalltalk не был создан на пустом месте. Идея динамической среды исполнения с возможностью собственной модификации и средствами мета программирования были взяты из Lisp. Концепция классов пришла из Simula-67, который был первым языком, реализующих некоторые важные принципы объектно-ориентированного программирования.

А теперь перейдем к перечислению того, что, собственно, Smalltalk дал миру программирования.


Объектно-ориентированное программирование Править

Еще задолго до появления Smalltalk Алан Кей сформулировал три фундаментальных принципа объектно-ориентированного программирования:

  • Объект - базовая единица объектно-ориентированной системы.
  • Объекты могут обладать состоянием.
  • Посылка сообщения - единственный способ обмена информацией между объектами.

Таким образом, видно, что изначальное определение существенно отличается от привычного нам инкапсуляция-полиморфизм-наследование, которое уже имело место до появления Smalltalk в языке Simula-67.

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

Попробуем рассмотреть, в каком отношении находятся эти два определения.

  • Инкапсуляция. Естественным образом следует из первоначального определения, так как объекты заключают в себе свои данные и могут взаимодействовать только посредством посылки сообщения без возможности прямого доступа к внутренней структуре.
  • Полиморфизм. Входит в понятие посылки сообщения. Любое сообщение может быть послано произвольному объекту, который сам решает обрабатывать ли его, и если обрабатывать, то каким образом.
  • Наследование. Это понятие никоим образом не вводится в определении Алана Кея, так как, по сути, это всего лишь удобный механизм для повторного использования кода, что является, скорее, деталью реализации, а не базовым принципом. Если требовать наличия наследования, тогда под определение объектно-ориентированного языка не будут подпадать языки, основанные на прототипах (prototype-based languages), в которых повторное использование реализовано посредством операции делегирования.

Таким образом, видно, что первоначальное определение, данное Аланом Кеем, является более общим. Кроме того, как отмечает сам автор, операция посылки сообщения является нечто большим, чем операция вызова метода в традиционных языках. Это, пожалуй, самая мощная концепция объектно-ориентированного программирования, отказ от которой сильно снижает эффективность всей идеи.

Чем же таким особым обладает операция посылки сообщения (message passing), по сравнению с обычным вызовом метода (method invocation), который применяется в статически-типизированных языках?

Для начала, стоит разобрать из каких этапов состоят эти две операции.

И то, и другое имеет два основных этапа: поиск метода (method lookup) и собственно вызов метода (method invocation).

В статической системе первый этап выполняется компилятором при трансляции исходного кода в машинное представление. Тут снова появляется две альтернативы - раннее связывание (early binding) и позднее связывание (late binding). В первом случае компилятор заранее знает метод, который получит управление после операции вызова. Во втором случае для каждого класса (интерфейса) компилятор строит свою таблицу методов и использует индекс для извлечения результирующего метода на этапе выполнения. Первый механизм также называется статической диспетчеризацией (static dispatch), второй - статической диспетчеризацией на основе таблицы виртуальных методов (static vtable-based dispatch).

Операция посылки сообщения в динамической системе оба этапа осуществляет на стадии выполнения программы. Поиск метода (method lookup) выполняется каждый раз перед вызовом метода (method invocation). При этом, если результирующий метод не найден, выполняется поиск метода doesNotUnderstand:, который является стандартным обработчиком события "метод не найден". В среде разработки это вызовет окно отладчика, в работающей системе можно либо прервать текущий процесс/нить или продолжить выполнение с занесением сообщения в лог-файл. Описанный механизм называется динамической диспетчеризацией (dynamic dispatch).

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

Очевидное применение, которое сразу приходит на ум - это различные схемы с прокси-объектами. То есть, можно вместо необходимого объекта, передавать его прокси (одного вида прокси с одним методом doesNotUnderstand: достаточно для работы с любыми объектами), который будет прозрачным образом перенаправлять все вызовы и возвращать результат.

Области, в которых это находит применение: персистентность, распределенные системы, профилирование, сбор статистической информации и т.д.

К тому же, сама семантика посылки сообщения может быть модифицирована для привнесения новых возможностей в систему - аспектно-ориентированние программирование, контрактное проектирование, предусловия и постусловия и т.д.

Именно операция посылки сообщения является тем, что обеспечивает описанный Аланом Кеем рекурсивный дизайн системы, при котором даже наименьшая ее часть может обладать не меньшими возможностями, чем система в целом.


Графический пользовательский интерфейс Править

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

В ходе проекта были разработаны следующие технологии:

  • Операция растрового копирования BitBlt для графического дисплея;
  • Графический интерфейс пользователя с перекрывающимися окнами и всплывающими меню;
  • Поддержка манипулятора "мышь" для пользовательского интерфейса.

В 1979-ом году лабораторию Xerox PARC посетил Steve Jobs. Компания Apple как раз искала идеи для своей новой разработки, так как предыдущие попытки по созданию персонального компьютера заканчивались неудачей. Увидев технологии, связанные с графическим интерфейсом и языком Smalltalk, Steve Jobs понял их значимость, и использовал при разработке компьютера Apple Macintosh, который впоследствии оказался более чем успешным.

Дальнейшая история уже многим известна. Почему-то многие именно Apple считают родоначальником пользовательского интерфейса, хотя это детище лаборатории Xerox PARC.


Интегрированная среда разработки (IDE) Править

Традиционно, среда разработки Smalltalk считается самой продуктивной с точки зрения программирования. С момента появления языка, среда была неотъемлемой его частью. Это была одной из его главных концепций - программирование посредством манипулирования реальными объектами, быстрое прототипирование и эволюционный дизайн.

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

Практически все среды разработки Smalltalk имеют следующие утилиты/возможности:

  • Workspace - окно, в котором можно ввести любой код и выполнить одно из следующий действий: Evaluate it - выполнить блок кода, Display it - выполнить и вывести результат, Inspect it - выполнить и результат просмотреть в отдельном окне Object Inspector.
  • Inspector - позволяет просматривать внутреннее строение объекта - его значение, внутренние поля, индексированные поля для объектов с переменной длиной. Значения полей выводятся в окошке, аналогичном Workspace, в котором можно ввести любое выражение, нажать Accept, и полученное значение будет занесено в поле. Также для любого из полей можно вызвать отдельное окно Inspector.
  • Dolphin-class-browser
    Class Browser - утилита, в которой, собственно, и происходит разработка приложений. Она включает в себя три обязательных элемента (панели): иерархия всех классов в системе, список полей/методов выбранного класса, исходный текст выбранного метода. Еще метода могут быть разбиты на категории, что облегчает навигацию, но никак не влияет на их выполнение. Одновременно может быть открыто несколько окон Class Browser. Создавать приложения в нем значительно удобнее, чем при файловом представлении исходного кода, хотя поначалу это непривычно.
Этому также способствует всевозможные функции поиска:
  • найти класс по имени/шаблону;
  • найти методы по имени/шаблону;
  • найти методы, которые вызывает метод с заданным именем/шаблоном;
  • найти методы, содержащие заданный текст и т.д.
Также существует инструмент Method Finder, в котором через точку вводятся получатель, параметры, результат и выдается список методов, которые удовлетворяют заданному критерию.
Например, зададим следующий критерий: 3 . 4 . 7. Тогда результатом поиска будет список следующих методов класса SmallInteger: +, bitOr:, bitXor:.
  • Debugger также является основным инструментом разработки. Так как Smalltalk является динамическим языком, то в нем можно ввести синтаксически-корректную конструкцию, которая вызовет ошибку во время выполнения из-за того, что в объекте-получателе не найден нужный метод. На первый взгляд, это должно приводить к большому количеству ошибок, но практика показывает, что этого не происходит.
Дело в том, что подход к написанию программ в Smalltalk существенно отличается от традиционного.
Dolphin-debugger
Проиллюстрируем это примером: написание программы начинается с метода main, который вызывает method1. Сразу после написания метода мы вызываем его (из окна Workspace командой MyClass main), и, естественно, получаем ошибку, что method1 не найден; после этого мы открываем окно Class Browser, в котором реализуем недостающий метод и в отладчике перезапускаем метод main. Управление дойдет до method1, в котором возникнет другая ошибка; с ним мы проделаем то же самое и опять продолжим выполнение.
Таким образом можно итерационно строить программу не выходя из отладчика. Параллельно с этим можно использовать окна Workspace и Inspector для просмотра состояния выполняющейся программы и внесения необходимых изменений, где это нужно. Разработка упрощается за счет наличия контекста выполнения, из которого мы можем почерпнуть информацию, что и как должно быть реализовано на следующем шаге. И скорость такой разработки практически не уступает скорости написания и компиляции программ в статических языках.
В итоге получается, что программа, разработанная таким образом, может содержать даже меньшее количество ошибок, чем при использовании статически-типизированного языка (в котором ошибки несовпадения типов проверяются на этапе компиляции, но это лишь малая часть возможных ошибок), так как она уже по крайней мере один раз корректно выполнилась.

Также имеется ряд возможностей, которые не могут быть реализованы через пользовательский интерфейс, их нужно использовать в окне Workspace. В частности, чтобы получить список всех объектов заданного класса, нужно выполнить действие MyClass allInstances; а чтобы получить список объектов, которые ссылаются на заданный, нужно выполнить obj allReferences. Таким способом несложно узнать причину возникшей утечки памяти.

В различных реализациях Smalltalk также имеются свои специфические утилиты для создания пользовательского интерфейса, создания отдельного исполняемого файла и т.д.

В последнее время появляются среды разработки для других языков, которые по функциональности приближаются к средам разработки Smalltalk, в частности, продукты Eclipse и IDEA для языка Java. Но, все равно, возможности этих сред местами сильно ограничены нединамической природой самого языка.


Язык Self Править

В 1987-ом году сначала все с той же лаборатории Xerox PARC, а потом в Стэндфордском университете David Ungar и Randall Smith разработали новый язык программирования, который задумывался как продолжение языка Smalltalk. Это была экспериментальная разработка, целью которой было выяснить, насколько далеко можно продвинуться в направлении динамического чисто объектно-ориентированной системы программирования.

В итоге в языке Self были реализованы следующие концепции:

  • отсутствие классов; такие языки называются prototype-based; в них создание новых типов объектов осуществляется посредством клонирования имеющихся и внесения изменений непосредственно в структуру нового объекта; каждый объект представляет собой набор слотов одно из нескольких видов: константный (constant), переменный (variable) или родительский(parent), который задает наследование; также у объекта может быть activation record, которая делает объект методом;
  • отсутствие операции присваивания (:=), которая была в Smalltalk; присваивание значений локальных слотов и слотов в получателе (self) также осуществляется посредством посылки сообщения;
  • поддерживается множественное наследование путем делегирования, т.е. можно указать больше одного объекта, которые будут обрабатывать сообщения, не найденные в исходном объекте; в то же время, получателем сообщений, вызванных из родительских методов опять будет дочерний объект;
  • родительские слоты могут быть изменяемыми, т.е. поддерживается динамическое множественное наследование; очевидное применение - простая реализация шаблона проектирования State;
  • даже базовые объекты, которые в Smalltalk были зарезервированными словами (nil, true, false), тоже являются обычными слотами в корневом объекте и извлекаются посредством посылки сообщения; таким образом в языке Self осталось только одно зарезервированное слово (resend - делегирования вызова родительским объектам), в то время как в Smalltalk их было пять;
  • в Smalltalk некоторые арифметические операции и сообщения, отвечающие за условия и циклы обрабатываются компилятором специальным образом; это было сделано для улучшения производительности; в Self таких частных случаев нет, и абсолютно все сообщения трактуются одинаково; это означает, что даже простейшая условная конструкция требует две операции посылки сообщения и клонирования нескольких объектов;

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

Имея такие характеристики, трудно себе представить, что язык Self способен выполняться хотя бы умеренно медленно. Действительно, простая интерпретируемая реализация в лоб выполняет программы, написанные на Self, в сотни-тысячи раз медленнее, чем аналогичная программа на C.

Поэтому разработчики языка в первую очередь сконцентрировали свои усилия на создание эффективного динамического компилятора - Self dynamic compiler technology. Эта система эволюционировала в трех версиях и к 1993-ему году достигла невероятных результатов. Стандартный набор целочисленных тестов Стэндфордского университета выполнялся со скоростью 40% от скорости оптимизирующего компилятора C. Теория показала, что возможно достичь планки в 60%, и является пределом для динамических языков, если реализовать более качественное распределение машинного кода.

Еще более впечатляющие результаты могут быть достигнуты в алгоритмах с высокой степенью полиморфизма. Реальные приложения, как правило, и относятся к этой категории. В языках C/C++ полиморфизм реализуется посредством операции косвенного вызова (indirect call). А эта операция обходится очень дорого на современных суперскалярных процессорах. Динамический адаптивный компилятор Self способен реализовать полиморфный вызов так же хорошо, как и любой другой, или даже полностью исключить его посредством встраивания вызываемого метода в вызывающий (adaptive inlining). Таким образом программы на языках C/C++ показывают даже меньшую производительность на таких тестах.

Что же обеспечило настолько хороший результат? Вот технологии, которые были реализованы в динамическом компиляторе языка Self:

  • multi-generational garbage collector - для эффективного управления памятью;
  • компиляция одного и того же метода для разных получателей сообщения (customization);
  • полиморфный встроенный кэш вызовов (PIC);
  • сбор статистической информации о частоте вызовов каждого метода в системе с дальнейшей передачей этой информации адаптивному компилятору/декомпилятору.
  • динамическая компиляция часто вызываемого метода с возможностью встраивания нескольких методов вверх и вниз по цепочке вызовов;
  • динамическая декомпиляция с замещением методов на стеке в случае программных изменений; это необходимо для сохранения семантики языка, когда в произвольный момент времени может быть внесено изменение в структуру любого объекта.

Правда, следует отметить, что все эти технологии приводили к сильному перерасходу памяти, так что среда разработки Self для нормального функционирования требовала 64 мегабайта памяти.

Проект Self финансировался компанией Sun, и в 1994-ом году было решено официально закрыть проект. Видимо, в тот момент поменялась политическая обстановка внутри компании в связи с скорым выходом языка Java, куда и были брошены основные силы.


Animorphic Smalltalk Править

После закрытия проекта, создатели языка Self решили, что такие уникальные технологии должны найти свое применение. Для этого был открыт проект Animorphic Smalltalk, который должен был вобрать наработки языка Self с целью создания высокопроизводительной коммерческой реализации Smalltalk.

За два с лишним года компания Animorphic разработала динамический компилятор языка Smalltalk, который вобрал в себя все лучшее из Self и, в то же время, были решены многие проблемы. Теперь для отслеживания программных изменений требовалось всего лишь несколько сот килобайт дополнительной информации, в отличие от десятков мегайбайт в системе Self.

К тому же язык Smalltalk был расширен новыми возможностями. В него была добавлено множественное наследование посредством подмешиваний (mixins), реализована экспериментальная система необязательной проверки типов Strongtalk. Дополнительно, и без того мощная стандартная библиотека классов была переработана с целью лучшего повторного использования. А для графического интерфейса была написана новая библиотека, основанная на глифах (glyphs).

В компилятор был добавлен интерпретируемый режим для ускорения загрузки программы и сбора статистической информации для последующих вызовов динамического адаптивного компилятора.

Для эффективной сборки мусора был применен алгоритм train, который позволяет уничтожать долгоживущие объекты без заметных пауз во время выполнения программы.

В конце концов, Animorphic практически обрел черты коммерческого продукта, готового к выпуску. Но препятствием для его выхода стала все та же компания Sun, которая раньше спонсировала развитие языка Self.


Java HotSpot VM Править

Одно из преимуществ, которое отличает динамически типизированные языки программирования (такие, как Smalltalk) от статически типизированных (например, Java), является их однородность и масштабируемость.

Проиллюстрируем это примером.

В языке Java поддерживается несколько типов выполнения операций над объектами:

  • арифметические операции с примитивными типами данных; например, сложение и вычитание целых чисел;
  • вызов статического метода;
  • вызов виртуального метода;
  • вызов виртуального метода через интерфейс;
  • вызов посредством рефлексии (reflexion).

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

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

В языке Smalltalk ситуация иная - операция посылки сообщения имеет тот же вид как для арифметических, так и для любых других операций. А использование рефлексии снижает производительность на считанные проценты! То есть, в языке имеется всего лишь одна базовая конструкция, которая и определяет скорость выполнения приложений. Соответственно, если эта конструкция будет выполняться максимально быстро, то это скажется положительно на всех без исключения приложениях.

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

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

В Smalltalk все сложнее - даже самые маленькие приложения постоянно создают много новых объектов. По статистике 95% вновь созданных объектов имеют очень короткий срок жизни. Та же картина наблюдается и для больших систем. Поэтому с самого начала перед резработчиками Smalltalk ставится трудная задача - минимизировать влияние алгоритмов сборки мусора на работу приложения. Это особенно критично в графических приложениях, где паузы, вызванные работой менеджера памяти, недопустимы.

Складывая все факторы вместе, получается, что эффективная реализация языка Smalltalk будет давать хорошую и предсказуемую производительность для систем любого масштаба. Определяющей величиной скорости выполнения приложения являются только количество операций посылки сообщения.

С языком Java ситуация намного сложнее - быстрое выполнение целочисленных тестов еще абсолютно ничего не говорит о работе реальных приложений.

Компания Sun, естественно, была в курсе такого положения вещей. Вплоть до JDK 1.2 графические и серверные приложения выполнялись медленно, порой даже очень медленно.

С этим, безусловно, нужно было что-то делать, и Sun сделала - в 1997-ом году она купила компанию Animorphic! Зная историю развития проекта со времен Self compiler technology, она сделала ставку на динамический адаптивный компилятор. Ядро компилятора Animorphic Smalltalk было адаптировано для языка Java, и проект получил название Java HotSpot Virtual Machine. Имя проекта отражало способность компилятора динамически определять наиболее критичные участки приложения и создавать для них высоко оптимизированный машинный код.

Но, видимо, время до выпуска JDK 1.3 оставалось немного, поэтому не все возможности были реализованы в HotSpot VM, например полиморфный кэш вызовов. Также не было сделано качественной реализации работы с примитивными типами данных. Из-за этого HotSpot VM проигрывала на простых целочисленных тестам предыдущим версиям JDK. Но ситуация коренным образом поменялась для реальных приложений. Наконец, их скорость выполнения стала приемлемой.

С выходом JDK 1.4 динамический компилятор был существенно доработан - реализована качественная поддержка примитивных типов данных, рефлексивные вызовы стали выполняться в десятки раз быстрее. А также, добавлены присущие Self и Smalltalk динамические возможности для подмены методов во время отладки.

Естественно, покупка Animorhic Smalltalk компанией Sun сделало невозможным выход этого коммерческого продукта. Но, учитывая многочисленные просьбы сообщества разработчиков, была выложена экспериментальная версия Animorphic Smalltalk 1.1.1, правда без исходных текстов компилятора.

VisualAge for Java Править

Этот факт также может показаться удивительным, но, тем не менее, одна из самых продуктивных сред разработки на языке Java написана на Smalltalk (Visual Age for Smalltalk). Этот продукт по возможностям в целом повторяет своего прародителя, но язык Java накладывает серьезные ограничения на многие динамические функции среды.

Правда, проект VisualAge доживает свои последние дни. В настоящее время компания IBM активно занимается продвижением своего нового продукта - Eclipse. Это среда разработки для языка Java, которая построена на базе новой библиотеке визуальных элементов интерфейса SWT. Главное отличие от стандартной библиотеки AWT - это легковесность и простота использования.

И, как раз, основные черты SWT были позаимствованы у платформонезависимого набора компонент, разработанного еще для Visual Age for Smalltalk.


Архитектура SPARC Править

Во все времена была популярна идея создания процессора адаптированного для эффективного выполнения команд определенного языка. В начале восьмидесятых все тот же David Ungar работал над проектом Smalltalk-on-a-Risc (SOAR). В ходе проекта были использованы/разработаны следующие технологии:

  • Большой набор регистров;
  • Тэговая арифметика;
  • Отложенная обработка ловушек;
  • Регистровые окна;
  • Малая стоимость команды вызова;
  • Малая стоимость косвенного обращения к памяти.

Правда, в ходе исследований выяснилось, что специализированная архитектура не дает существенного выигрыша в производительности. В среднем получается значение около 30%. Поэтому большого смысла в создании такого процессора не было.

Но эти наработки, все-таки, не пропали даром, многие из них впоследствии были реализованы в архитектуре SPARC.

Продолжение следует.

10.02.2003, Владимир Лешкевич

Ссылки по теме Править

Обнаружено использование расширения AdBlock.


Викия — это свободный ресурс, который существует и развивается за счёт рекламы. Для блокирующих рекламу пользователей мы предоставляем модифицированную версию сайта.

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

Также на ФЭНДОМЕ

Случайная вики