Задать вопрос
  • Почему нет процессоров построенных на MISC архитектуре?

    @stinky97
    Самоучка
    Насколько мне известно, MISC - скорее философия, чем конкретное название семейства стековых процессоров. То есть им потенциально может быть и процессор не с 0-операндного (0-operand) системой команд. Однако, если рассматривать именно стековые реализации, то можно назвать несколько причин их коммерческой нераспространенности (они довольно субъективны и я уверен, что можно назвать более очевидные, а как минимум некоторую часть можно оспорить): сложности при обеспечении внеочередного выполнения (out-of-order execution) или иной возможности повышения производительности на уровне команд (instruction level parallelism, ILP) и не настолько существенная плотность кода в распространенных реализациях, насколько она казалась возможной в теории (что в конечном счете тоже оказывает влияние на производительность).
    Первая проблема, возможно, достаточно очевидна, если принять во внимание последовательную природу стека: каждая следующия вычислительная инструкция зависит от результатов предыдущей. Помимо вычислительных инструкций существуют и те, что меняют положение элементов на стеке или совершают некое "обслуживание" состояния стека - DUP, DROP, SWAP, ROT и другие (названия были приведены по примеру стековых операций языка Forth). Если представить процесс декодирования инструкций в простом игрушечном процессоре с несколькими функциональными блоками (условные 4 декодера, соответствующие инструкциям одинаковой ширины), можно понять, что такие инструкции могут указать, какой элемент со стека должен принять следующий свободный функциональный блок процессора (execution unit). В данном примере я мог не очень реалистично и практично описать работу гипотетического устройства декодирования инструкций, но для понимания нужна хоть какая-то аналогия. Получается, что каждая следующая инструкция при декодировании обязательно опирается на предыдущую, то есть логика работы будет работать по сложности линейно. С другой стороны, простые ядра (потоки) без "наворотов" с маленькими в размерах инструкциями могут эффективно размещаться на кристалле в больших количествах, предоставляя (возможно) огромный потенциал для других видов параллелизма с минимальной конкуренцией за дефицитные и разделяемые всеми ядрами (потоками) ресурсы.
    Вторая проблема - программа может нуждаться в постоянном "жонглировании" элементами на стеке. То есть каждой полезной операции (к примеру, арифметической) будет в комплект идти SWAP, ROT и компания, что в зависимости от конкретного типа запускаемой на процессоре программы может привести к падению "полезной" нагрузки настолько, что ценность одной инструкции такого процессора будет сопоставима с 0.4-0.5 инструкциями 3-операндного RISC процессора. Конечно, никто не исключает возможности создания набора команд, включающего в себя биты операции на стеке после выполнения какой-нибудь полезной операции. Несмотря на положительный эффект, оказываемый на производительность, это могло бы негативно сказаться на плотности кода.
    Сама модель стекового процессора может оказаться не привычна программистам, что теоритически могло бы замедлить портирование некоторого уже существующего программного обеспечения (если рассматривать применение таких процессоров в general-purpose среде).
    Если кто-то заинтересуется в решении существующих проблем - некоторые исследования по многоядерным процессорам и внеочередному выполнению (BOOST - Berkeley Out-of-Order Stack Thingy, на эту работу часто ссылаются как на контраргумент к одному из заявляемых недостатков) уже были проведены.
    Немного отходя от темы, приведу набор интересных идей, какие-то из них были подсмотрены в когда-то существовавших решениях, какие-то (не особо успешные) сами пришли ко мне в голову: решением проблемы с ILP может быть указание позиции операнда на стеке в инструкциях, претендующих на параллельное выполнение. Также, если не жалко места в инструкции, можно приглядеться к выборочной деструктивности операндов на стеке как способу избавления от DUP-ов (игра, по результатам замеров, свеч не стоит). Ну и наконец, было бы здорово увидеть реализацию такой интересной ранее изученной концепции, как runahead execution - потенциально может помочь с выполнением инструкций "наперед", рассматривая зависимости во время долгих загрузок из памяти или иных операций, занимающих несколько (предположительно много) тактов.
    Уже существующие FPGA-реализации процессоров, которые могут немного вдохновить на расширение кругозора:
    - J1 и огромное количество его "потомков", очень известен, имеются fpga-реализации полноценных систем с VGA выводом, терминалом и клавиатурой.
    - 4stack, очень подробно расписанный в доступной в сети (дипломной?) работе; VLIW, преумножающий свои преимущества и приуменьшающий свои недостатки наличием четырех стеков.
    - sTTAck, один из немногих процессоров на TTA (transport triggered architecture); довольно интересный подход к управлению потоком данных.
    Еще можно прочесть книгу "Stack Computers: the new wave (1989)" Philip J. Koopman, описывающую набор команд и архетекутуру множества стековых процессоров как раз перед тем, как о них почти не стало ничего слышно.
    Ответ написан
    Комментировать