Нет, я не раскрою вам тайную, прячущуюся в заглавии MCp0411100101, но попытаюсь развёрнуто ответить на комментарий nerudo, записанный в топике Процессоры «Мультиклет» стали дешевее:Просматривая описание архитектурных новшевств этого мультиклета, мне хочется воспользоваться фразой из соседнего топика: «Я не осознаю».
Смотрите кроме этого: Мультиклет: Первые производительность и практические тесты
В мои руки попала отладочная плата мультиклета, и результатами его тестирования желаю поделится. Кроме этого поведаю и о нескольких подводных камнях, каковые на первых порах смогут пара подпортить нервы тем, кто захочет лично потрогать Мультиклет.Сходу стоит подметить, что я разглядываю лишь разработку на C (а не на Ассемблере) т.к. в наше время время работы программистов стоит дороже мегагерцев и памяти. У С-компилятора Мультиклета тяжелая будущее, и на _данный момент_ он будет в зачаточном состоянии (в частности, не реализованы какие-либо оптимизации).
В случае если коротко, то MCp — это потоковый (от dataflow) процессор с уникальной EPIC-архитектурой. EPIC — это Explicitly Parallel Instruction Computing, вычисления с явным параллелизмом руководств. Я использую данный термин тут как раз в этом смысле, как сокращение, а не как ссылку на архитектуру Itanium-ов.
Явный параллелизм в MCp совсем другого рода.О преимуществах MCpДля затравки я сообщу, что EPIC в MCp таковой, что наделяет процессор рядом заманчивых (по крайней мере лично для меня) особенностей.
- Хорошей энергоэффективностью. Которая обеспечивается тем, что MCp может:
- согласовывать собственное архитектурное состояние значительно реже, чем процессоры традицинных архитектур;
- естественным образом совмещать в параллельном асинхронном выполнении инструкции работы с памятью, арифметические руководства и предвыборку кода.
- Нестандартная организация ветвлений даёт увлекательные возможности реализации, так называемых, managed runtime, либо (в хорошей терминологии) надёжных языков программирования.
- Функциональные языки возможно положить на архитектуру MCp «естественней», чем на классические автомобили.
- Особенность кодирования программ (подразумевается машинный код) и особенность их выполнения разрешают сделать MCp неспешно деградирующим процессором. Другими словами, он может не ломаться полностью, при отказе функциональных устройств, а переходить в режим работы с другим распределением вычислений, с меньшей производительностью, конечно. В отличии от классических отказоустойчивых процессоров, у которых функциональные устройства (либо сами процессоры полностью) легко троированы, MCp в штатном режиме, в то время, когда аппаратные неточности не появляются, может действеннее применять собственные вычислительные мощности.
- Ко всему этому MCp ещё довольно легко возможно масштабировать (разрешал бы техпроцесс) и запускать в режиме многопоточности (имеется в виду SMT — Simultaneous Multi Threading) да ещё и с динамическим разделением ресурсов между нитями.
Сейчас я попытаюсь растолковать, откуда эти особенности берутся, и откуда такое наименование «мултиклеточный», другими словами, что такое «клетка». О таинственных цифрах в маркировке мне ничего не известно. Возможно, это ключ какого-нибудь «MultiClet»-квеста? 🙂 Нет, я серьёзно не знаю.КлеткиКлетка (такое уж наименование) — это основный элемент микроархитектуры MCp.
Возможно, существует и более простое объяснение того, что это такое, но мне несложнее начать с описания существующих процессоров.Любой современный CPU содержит комплект неких функциональных устройств. Их возможно поделить на пара типов. Давайте поделим (для пояснения изюминок MCp мне не пригодятся уж весьма детальное их описание, исходя из этого всё поверхностно).
- ALU: арифметико-логические устройства, в широком смысле. Другими словами, устройства, каковые делают всевозможные преобразования над данными. У них имеется входные порты, на каковые подаётся операнды и код операции и выходные, на которых формируются результаты.
- LSU: устройства доступа в память (Load/Store Unit). Конечно, эта вещь эти не преобразовывает, а записывает либо считывает из памяти. У неё собственные входные и выходные порты.
- RF: регистровый файл. Эти устройства сохраняют эти с некоторых шин (не совсем верное наименование, но не сущность) и выдают их на другие шины, ориентируясь на значения и команды на собственных входных портах. Шины эти связаны с портами LSU либо ALU. Довольно часто говорят, что регистры — это такая стремительная внутренняя память процессора. Вернее заявить, что RF — это такая весьма действенная внутренняя память процессора, а семантика регистров — это интерфейсы для доступа к нему. По причине того, что, существует Его Величество…
- очень: устройство контроля. Это устройство, которое руководит множеством ALU, LSU и RF (на данный момент модно делать один неспециализированный RF на ядро, но не всегда было так; ), осуществляя контроль передачу сигналов между ними, делая программу. В современных классических высокопроизводительных процессорах само CU сверхсложное, и складывается из вторых компонент: планировщиков, предсказателей переходов, декодеров, очередей, буферов подтверждения и т.д. Но для целей этого рассказа мне эргономичнее вычислять всё это одним устройством. Совершенно верно так же я не раскладываю на сумматоры и сдвигатели ALU.
Возможно заявить, что CU — это устройство, определяющее тип процессора. Практически во всех современных классических процессорах ALU, LSU и RF с функциональной точки зрения устроены приблизительно одинаково (если не вдаваться в узкие подробности реализации и не делать различий между векторными и скалярными ALU; да, согласен высказывание оказалось условным).
Всё многообразие моделей CPU, GPU, PPU, SPU и других xPU обеспечивается отличием в логике работы различных вариантов CU (и эта отличие значительно значительнее, чем отличие между векторными и скалярными ALU).Это возможно логика несложного стекового процессора, CU которого обязан трудиться по тривиальному циклу. Прочесть из собственного RF, складывающегося из двух регистров IP (указатель на текущую инструкци) и SP (вершину цикла), оба регистра.
Выставить на входные порты LSU содержимое операции и код чтения IP (вероятнее, CU в этом случае легко скоммутирует выход RF и вход LSU), узнать ответ — код инструкции. В случае если, допустим, это код инструкции перехода, то CU обязан выставить на портах LSU запрос на чтение значения из вершины стека, поменять SP на единичку, послать это значение в RF, а на следующем такте скоммутировать выходной порт LSU с входным портом RF (на другой порт выставив значение, соответствующее записи в IP).
После этого, повторить цикл. В действительности, весьма легко. Думается, что зря в отечественных профильных вузах не разрабатывают стековые процессоры в качестве упражнения.Это возможно логика навороченного суперскалярного и многонитевого POWER8 с дополнительным выполнением, что за любой такт выбирает по паре руководств, декодирует прошлую выборку, переименовывает регистры, рулит огромным регистровым файлом (кроме того у i686 с его видимыми 16-ю регистрами, регистровые файлы могли быть размером в 128×64 битов), предвещает ветвления и т.д.
Таковой процессор уже не сделаешь в виде домашнего задания.Либо это возможно также достаточно простой RISC-подобный CU, что в GPU раздаёт всем ALU, LSU и RF, упакованным в мультипроцессор, одну и ту же команду.В современном высокопроизводительном CPU как раз CU есть самым сложным устройством, которое занимает солидную часть чипа. Но это пока не важно.
Основное, что во всех перечисленных случаях CU — одно, хоть и может наряду с этим загружать работой и осуществлять контроль множество вторых функциональных устройств. Что возможно эквивалентно сформулировать и без того: в современных процессорах возможно делать пара потоков управления (цепочек руководств) при помощи одного CU (SMT, к примеру, Hyper Threading); но нельзя выполнять один поток управления при помощи нескольких CU.Ага!
Мой юный падаван (мы же все молоды духом и знаем, что ничего не знаем 🙂 разгадка тайны Мультиклета близка. Конечно, на данный момент я сообщу, что дизайн мультиклеточного процессора таков, что он содержит в себе пара CU, трудящихся по определённому протоколу и формирующих наряду с этим некое распределённое CU, которое может выполнять один поток выполнения (одну нить, другими словами, thread) на нескольких ядрах. Но вначале я сообщу второе.Так вот, клетка — это аналог ядра в привычном CPU.
Она содержит собственное CU, ALU (одно, но достаточно продвинутое кроме того в ранней версии процессора, талантливое делать операции с float[2] значениями, среди них и операции комплексной математики; разрабатываемая на данный момент версия будет поддерживать вычисления с double). Клетки смогут иметь доступ к неспециализированным RF и LSU, либо смогут иметь собственные, каковые смогут трудиться в режиме зеркал либо кроме того RAID-5 (в случае если потребуется; не забывайте, самое ответственное на данном этапе развития проекта слово — «отказоустойчивость»).
И одно из самых приятных мест в архитектуре MCp — то, что не смотря на то, что в таких режимах RF и будет трудиться заметно медленней, производительность MCp значительно это не снизит, поскольку главный обмен данными на протяжении вычисления идёт не через RF и шунты (bypass), а через второе не являющееся памятью устройство — коммутатор.Основной изюминкой клеток есть то, что их CU смогут, трудясь по особенному протоколу и с особенным понятием программы, совместно составлять один распределённый CU, что может делать одну нить (в смысле, thread, в смысле, поток управления). И делать они эту нить смогут в параллельном, асинхронном, совмещённом режиме, в то время, когда в один момент происходят: выборка руководств, работа с памятью и RF (это весьма няшным методом делается), арифметические преобразования, вычисление цели перехода (а от этого я лично по большому счету балдею, потому что pattern-matching из высокоуровневых языков на это превосходно укладывается).
И, что ещё более превосходно, эти CU оказались намного более очень сильно значительнее 🙂 реально несложнее, чем CU современных суперскалярных процессоров с дополнительным выполнением. Они также способны на такое параллельное выполнение программы (уточню: но не за счёт собственной простоты и распределённости, а напротив, за счёт собственной сложности и централизованности, каковые необходимы для создания особенных знаний об исполняемой программе; подробнее в следующей части текста).По моему точке зрения (которое может различаться от мнения самих инженеров, создавших и совершенствующих MCp), самая ответственное достижение в процессоре — это как раз такие CU, как раз они и снабжают серьёзные на текущем этапе существования процессора энергоэффективность и отказоустойчивость.
А сам предложенный принцип их построения серьёзен не только для процессоров, но и для других высокопроизводительных распределённых вычислительных совокупностей (к примеру, по похожим правилам строится совокупность RiDE).Энергоэффективность. MCp — параллельный процессор, талантливый выполнять 4 инструкции за такт, это совсем хорошо. И для этого ему не требуется сложное и громадное (по своим размерам) центральное CU, он обходится относительно маленькими локальными для каждой клетки устройствами.
Мелкие, значит потребляют меньше энергии. Локальные, значит, возможно обойтись более маленькими проводками для передачи сигналов, значит, меньше энергии будет рассеиваться, и выше частотный потенциал. Это всё +3 к энергоэффективности.Отказоустойчивость. В случае если в традицонном процессоре погибает CU, то погибает целый процессор.
В случае если в MCp погибает один из CU, то погибает одна из клеток. Но процесс вычисления может длиться на оставшихся клетках, хоть и медленней. Простые процессоры, традиционно, троируют для обеспечения надёжности.
Другими словами, ставят три процессора, каковые делают одну и ту же программу. В случае если один из них начинает сбоить, это обнаруживается и его отключают. Архитектура MCp разрешает процессору трудиться в таком режиме самому по себе, и это возможно осуществлять контроль программно: в случае если нужно, можно считать в высокопроизводительном режиме, в то время, когда нужно, можно считать в режиме с перекрёстной проверкой результатов, не тратя на это дополнительные аппаратные ресурсы, каковые также смогут отказать.
Вероятны и другие режимы (до тех пор пока, как мне известно, их не запатентовали, исходя из этого не буду распространяться).Рождение нелинейностиТеперь я постараюсь растолковать, из-за чего таковой распределённый CU вероятен, что он вправду возможно несложным, из-за чего для этого нужен второй метод кодирования программы, и из-за чего данный метод, предложенный авторами MCp, клёвый. Мне опять несложнее начать с описания классических (GPU и VLIW также считаются классическими) архитектур.Давайте-ка я уже что-нибудь скомпилирую, в противном случае уже два дня ничего не компилировал, руки чешутся уже.cat test-habr.c gcc -S test-habr.c cat test-habr.stypedef struct arrst Arrst;struct arrst { void * p; char a[27]; unsigned x; };struct st2 { Arrst a[23]; struct st2 * ptr; };struct st2 fn5(unsigned x, char y, int z, char w, double r, Arrst a, Arrst b) { int la[27]; char lb[27]; double lc[4]; struct st2 ld[1]; return ((struct st2 *)b.p)[a.a[((Arrst *)b.p)-a[13]]].ptr-ptr-ptr[lb[10]]; } .file test-habr.c .text .globl fn5 .type fn5, @function fn5: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $1016, %rsp movq %rdi, -1112(%rbp) movl %esi, -1116(%rbp) movl %edx, %eax movl %ecx, -1124(%rbp) movl %r8d, %edx movsd %xmm0, -1136(%rbp) movb %al, -1120(%rbp) movb %dl, -1128(%rbp) movq 56(%rbp), %rdx movq 56(%rbp), %rax movzbl 21(%rax), %eax movsbl %al, %eax cltq movzbl 24(%rbp,%rax), %eax movsbq %al, %rax imulq $928, %rax, %rax addq %rdx, %rax movq 920(%rax), %rax movq 920(%rax), %rax movq 920(%rax), %rdx movzbl -134(%rbp), %eax movsbq %al, %rax imulq $928, %rax, %rax leaq (%rdx,%rax), %rcx movq -1112(%rbp), %rax movq %rax, %rdx movq %rcx, %rsi movl $116, %eax movq %rdx, %rdi movq %rax, %rcx rep movsq movq -1112(%rbp), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size fn5, .-fn5 .ident GCC: (GNU) 4.7.2 .section .note.GNU-stack,,@progbitsЭто классический ассемблер для регистровой автомобили.
То, что таковой код возможно выполнить лишь при помощи одного CU, отлично демонстрирует вот эта цепочка (напомню, что в ассемблере ATT запись происходит в правый операнд): imulq $928, %rax, %rax addq %rdx, %rax movq 920(%rax), %rax movq 920(%rax), %rax movq 920(%rax), %rdx movzbl -134(%rbp), %eaxМедитируя над этим кодом, возможно заявить, что первые пять руководств необходимо делать строго друг за другом, а последнюю, 6-ую, возможно было бы запустить и параллельно со всеми прошлыми руководствами. Но в самих руководствах конкретно информации о том, что так выполнить код возможно, не содержится. Практически, в классическом коде с регистрами привязка инструкции к обрабатываемым данным осуществляется единственным методом: установкой инструкции на определённое место в линейно-упорядоченной цепочке команд.Любая инструкция, как бы, есть оператором, что действует на некое значение — архитектурное состояние процессора (по идее, само собой разумеется, она может функционировать и на память, и на внешний мир, и для формальности и полной строгости нужно сказать и об этом; но CU процессора может отвечать лишь за процессор; математикам это жутко не нравится, кстати) — которое сформировалось в следствии исполнения предшествующих руководств (с учётом ветвлений, само собой разумеется). Дабы попытаться выполнять данный код при помощи нескольких свободных CU асинхронно необходимо ответить на вопросы:
- как между этими CU поделить архитектурное состояние?
- как выяснить, к какой части архитектурного состояния направляться применить очередную (какую как раз?) инструкцию, дабы сохранить семантику кода?
- как позже собрать всё совместно?
- необходимо ли обмениваться архитектурными состояними?
Для ответа на эти вопросы необходимо разбирать код в соответствии с его последовательной семантике, в то время, когда следующая инструкция используется к итогам работы всех прошлых, и собирать данные об этом анализе в одном месте. Другими словами, для этого нужна некая единая точка анализа, один CU. Всеми любимые суперскалярные с дополнительным выполнением Core iX, либо AMD FX, либо POWER8 могут проводить таковой анализ и планировать выполнение кода на его базе.
CU этих процессоров способен на такие «чудеса», другими словами, на разбор цепочки последовательного кода в свободные параллельные кусочки, и на сборку его обратно в последовательную цепочку завершения операций. Но нет ничего, что получается само собой. Такие CU — самые затратные как по транзисторному бюджету, так и по энергопотреблению устройства в современных высокопроизводительных CPU.
Это сверхсложные схемы. Возможно кроме того сообщить, шедевральные. Думается, за изобретение первой таковой была присуждена премия Тьюринга.Возможно, лучше один раз заметить.
Это фотография кристалла VIA Isaiah (не самый сложный процессор) с разметкой функциональных блоков. Всё, что не относится к кэшам, PLL, FP, IU, Load/Store — это схемы управления выполнением.Как раз исходя из этого ARM играется в big.LITTLE, по причине того, что они не смогут сделать одновременно и экономный, и производительный процессор, опираясь на классическую архитектуру с регистрами.
И как раз исходя из этого, NVIDIA может стучать себя пяткой в грудь и информировать, что в одном ядре их процессора в 4 раза больше арифметических устройств, чем в одном ядре Sandy Bridge. У SB другое место занято схемами планирования и анализа выполнения потока линейно-упорядоченных руководств.В VLIW и в варианте EPIC от Intel и HP (Itanium) семантика руководств совершенно верно такая же: они должны исполнятся приятель за дружкой, изменяя архитектурное состояние процессора (грубо говоря, значения в регистрах).
Да, инструкции у таких процессоров сложные и кодируют исполнение солидного числа операций. Но необходимость в линейной упорядоченности этих сложных руководств сохраняется. Исходя из этого CU в VLIW-процессорах и Itanium-ах не может быть распределённым.
Само собой разумеется, в этих процессорах CU намного проще, чем в процессорах с дополнительным выполнением руководств. Но и у этих архитектур имеется собственные недочёты, которых нет в MCp. К примеру, для поддержания большого темпа выполнения кода VLIW процессоры должны владеть сложными регистровыми файлами: на каждом такте в них в один момент может записываться аж до 6-ти значений (одна из моделей Itanium) одновременно и вычитываться, соответственно, 12.
Имеется неприятность и при работе с памятью: в случае если инструкция содержит операцию доступа к области памяти, ещё не отображённой в кэш (либо другую стремительную память), то целый VLIW процессор останавливается и ожидает завершения данной операции. В Itanium эту проблему пробовали решить принудительными программными prefetch-ами, но оказалось прекрасно лишь для научных вычислений. У них структура доступа в память регулярна, предсказуема и выводится на этапе компиляции.
На вторых же высокопроизводительных рынках царствуют (до тех пор пока) или RISC SMT-процессоры, или процессоры с дополнительным выполнением, каковые смогут делать другую работу при задержках на протяжении доступов к памяти.Итак. Классическое кодирование программы в виде линейно-упорядоченной последовательности руководств, ссылающихся на регистры, требует наличия централизованного CU (весьма сложного, в случае если хочется действенно трудиться с памятью и несколькими ALU).
Что обязан руководить всеми другими устройствами в процессоре (исходя из этого, чем больше устройств, тем больше данный CU и сложнее). Что потребляет большое количество энергии и есть критической точкой отказа всего процессора.В этом месте инженеры «Мультиклет» делают красивый финт ушами и ставят перед общественностью вопрос: а для чего нам привязываться к линейному порядку при кодировании программы? А позже ещё более изящно и гениально отвечают на него: а не за чем!Параграфы и переходыУра!
Снова compilation time! взглянуть на ту же самую программу детальками (нет, глаза мы к нему ещё не приделали) MCp.cat test-habr.c rcc -target=mcp test-habr.ctypedef struct arrst Arrst;struct arrst { void * p; char a[27]; unsigned x; };struct st2 { Arrst a[23]; struct st2 * ptr; };struct st2 fn5(unsigned x, char y, int z, char w, double r, Arrst a, Arrst b) { int la[27]; char lb[27]; double lc[4]; struct st2 ld[1]; return ((struct st2 *)b.p)[a.a[((Arrst *)b.p)-a[13]]].ptr-ptr-ptr[lb[10]]; } Потом мало почищенный ассемблер: я убрал для удобства отечественные отладочные технические коментарии и директивы .local/.global (они сути не меняют). Директива .alias, играет роль #define.
Она употребляется для увеличения читаемости кода. Все неоптимальности и глупости компилятора сохранены. Он у нас ещё некое время будет на стадии beta-версии (нужной уже, однако, для работы с процессором и выдающей корректный код). Исходя из этого не судите уж через чур строго. О разных техниках оптимизации мы знаем и будем их неспешно внедрять. А до тех пор пока это вправду простой и неоптимальный код, чего уж скрывать.
Но мы же обсуждаем архитектуру самого процессора, а не компилятор..alias SP 39 ; stack pointer .alias BP 38 ; function frame base pointer .alias SI 37 ; source address .alias DI 36 ; destination address .alias CX 35 ; counter.textfn5: .alias fn5.2.0C #BP,8 .alias fn5.x.4C #BP,12 .alias fn5.y.8C #BP,16 .alias fn5.z.12C #BP,20 .alias fn5.w.16C #BP,24 .alias fn5.r.20C #BP,28 .alias fn5.a.24C #BP,32 .alias fn5.b.60C #BP,68 .alias fn5.2.0A #BP,8 .alias fn5.x.4A #BP,12 .alias fn5.y.8A #BP,16 .alias fn5.z.12A #BP,20 .alias fn5.w.16A #BP,24 .alias fn5.r.20A #BP,28 .alias fn5.a.24A #BP,32 .alias fn5.b.60A #BP,68 .alias fn5.lb.27AD #BP,-27 .alias fn5.1.32RT #BP,-32 .alias fn5.2.36RT #BP,-36 .alias fn5.3.40RT #BP,-40 .alias fn5.4.44RT #BP,-44 .alias fn5.5.48RT #BP,-48 jmp fn5.P0 getl #SP getl #BP subl @2, 4 subl @3, 56 wrl @3, @2 setl #SP, @2 setl #BP, @4 completefn5.P0: jmp fn5.P1 rdsl fn5.y.8C wrsb @1, fn5.y.8A completefn5.P1: jmp fn5.P2 rdsl fn5.w.16C wrsb @1, fn5.w.16A completefn5.P2: jmp fn5.P3 getsl 0x340 wrsl @1, fn5.1.32RT completefn5.P3: jmp fn5.P4 rdsb fn5.lb.27AD + 10 rdsl fn5.1.32RT mulsl @1, @2 wrsl @1, fn5.2.36RT completefn5.P4: jmp fn5.P5 rdl fn5.b.60A wrl @1, fn5.3.40RT completefn5.P5: jmp fn5.P6 rdl fn5.3.40RT addl @1, 0x11 rdsb @1 exa fn5.a.24A + 4 addl @2, @1 rdsb @1 rdsl fn5.1.32RT mulsl @1, @2 wrsl @1, fn5.4.44RT completefn5.P6: jmp fn5.P7 getsl 0x33c wrsl @1, fn5.5.48RT completefn5.P7: jmp fn5.P7.blkloop rdl fn5.3.40RT rdsl fn5.4.44RT rdsl fn5.5.48RT addl @2, @3 addl @1, @2 rdsl fn5.5.48RT rdl @2 addl @1, @2 rdsl fn5.5.48RT rdl @2 addl @1, @2 rdl @1 rdsl fn5.2.36RT addl @1, @2 rdl fn5.2.0A; Данный кошмар — настройка на копирование структуры 🙂 getl 0x0000ffff patch @1, @3 patch @2, @3 setq #SI, @2 setq #DI, @2 getl 0xfcc1ffff patch @1, 0 setq #CX, @1 getl #MODR or @1, 0x38 setl #MODR, @1 complete; само копирование, регистры с номерами CX, SI и DI изменяются машинально fn5.P7.blkloop: exa #CX jne @1, fn5.P7.blkloop je @2, fn5.P7.blkclean rdb #SI wrb @1, #DI completefn5.P7.blkclean: jmp fn5.PF getl #MODR and @1, 0xffffffc7 setl #MODR, @1 completefn5.1L: fn5.PF: rdl #BP, 4 jmp @1 getl #BP rdl #BP, 0 addl @2, 4 setl #BP, @2 setl #SP, @2 complete Похоже на простой ассемблер, но это чувство обманчиво. Сперва, направляться обратить внимание на то, что целый код разбит на участки между некоей меткой и флагом complete.
Таковой участок именуется параграф.Любой параграф содержит некоторый комплект руководств. Руководства бывают различными, кое-какие из них ссылаются на регистры (отмечены #), но кое-какие на значения, полученные в следствии исполнения прошлой инструкции. Ссылка имеет форму @N, где N — это расстояние до некоей предыдущей по коду параграфа инструкции, на итог которой и ссылается такое выражение.
Расстояние указывается в руководствах и, конечно, отсчитывается назад, другими словами снизу вверх по тексту от текущей команды.Другими словами, практически, при помощи @-ссылок в параграфе описывается граф потока данных некоего участка программы. И инструкции, по большей части, являются не операторами, каковые действуют на прошлое архитектурное состояние, а несложными операциями, каковые необходимо выполнить с одним либо двумя значениями.
Семантика у многих руководств MCp «легче» семантики классических руководств. Архитектурное же состояние меняют лишь инструкции записи в регистры (setX) либо записи в память (wrX).Мультиклеточный процессор, выполняя параграф, практически, делает редукцию графа потока данных, обрисованную кодом параграфа. Делает он это следующим образом.Допустим, в процессоре функционирует N клеток.
Тогда клетка с номером n, взяв адрес следующего для исполнения параграфа начинает считывать команды, каковые находятся в позициях N*k+n (k = 0, 1, …) параграфа, пока не встретит флаг complete (ассемблер позаботится о том, что она его встретит). И начинает делать готовые к выполнению инструкции.Руководства считаются готовыми к выполнению, в то время, когда клетка взяла все нужные для исполнения операнды.
В то время, когда инструкция выполнена, клетка информирует о её результате всем остальным клеткам и самой себе через широковещательный коммутатор процессора. К результату приписывается тег, по которому его возможно сопоставить с @-ссылкой (они именуются ссылками на коммутатор) какой-нибудь второй инструкции, хранящейся в буфере данной либо второй клетки.И цикл обнаружения готовых к выполнению рассылки и инструкций результатов их исполнения вторым клеткам повторяется.
Само собой разумеется, буферы, каковые разрешают отслеживать готовность руководств — довольно сложные устройства, но они намного-намного несложнее, чем CU классических процессоров с дополнительным выполнением. В случае если же сравнивать с VLIW и другими EPIC-процессорами, то клетки нормально переживают задержки при доступе к данным в памяти (либо в регистрах), по причине того, что, вероятнее, в буферах их CU готовься к выполнению инструкции, каковые не зависят от результатов данного конкретного чтения (либо записи).Но это ещё не всё.
Клетки по особенному трудятся с памятью и RF. Так как архитектура MCp предполагает, что нет никакой необходимости использовать инструкцию к архитектурному состоянию, то при исполнении операций доступа к RF либо памяти в рамках одного параграфа никакой порядок не фиксируется. Гарантируется только то, что все операции записи будут закончены до первого чтения данных из памяти либо RF в следующем параграфе.Вспомните респектабельный Load/Store/MOB модуль на диаграмме Isaiah.
Так вот, солидная его часть — это MOB, другими словами Memory Ordering Buffer. Особое устройство, которое оказывает помощь принимать решения о том, а возможно ли одну операцию чтения/записи осуществить до (либо по окончании) второй. Данный анализ также непростой: необходимо сравнивать зависимости и адреса.
Исходя из этого схема громадная.Клетка же постоянно говорит: ДА! Все выполняющиеся операции с памятью и RF возможно в пределах параграфа переставлять как угодно. И это быть может, по причине того, что у компилятора и программиста имеется средство выстроить необходимый порядок операций очевидно, при параграфов @-и помощи ссылок.
К примеру, конструкция:volatile a; a += a; транслируется в таковой код (мало схематично): rdsl a rdsl a addsl @1, @2 wrsl @1, a запись в котором, выполнится строго по окончании исполнения чтений, кроме того на не выполняющих порядок обращения к памяти клетках. Так, нужный порядок работы с памятью возможно задать без помощи сложного MOB, что приносит ещё +1 в копилку энергоэффективности MCp.Но и это ещё не всё. Сейчас самоё моё любимое.
По большому счету, потоковые архитектуры в истории процессоростроения появлялись множество раз, и любой раз отбрасывались. По причине того, что на чисто потоковой машине весьма сложно организовывать ветвления и циклы. Их организация лишь только в виде графа потока данных подразумевает, что в этом графе должны быть заблаговременно обрисованы все вероятные ветвления. Процессор же обязан таковой граф полностью загружать и выполнять. Для громадных программ это нереально.А в MCp эта неприятность решена изящно и просто.
Не считая нелинейного порядка между руководствами в параграфа, существует ещё и последовательный линейный (ну, в случае если уж совсем совершенно верно, то линейный темпоральный) порядок исполнение самих параграфов. В каждом параграфе может находиться пара руководств перехода: jmp (абсолютный переход) и jСС (разные условные переходы), через каковые вычисляется адрес параграфа, что нужно делать следующим.Когда срабатывает одна из руководств перехода, и в то время, когда все клетки уже достигли флага complete в параграфе текущем, они начинают выбирать инструкции следующего параграфа.
Исходя из этого в приведённом выше результате трансляции исходника на Си, jmp стоят в начале параграфов, и код наряду с этим исполняется нормально.Эта особенность MCp уже даёт как следует иные возможности в кодотворчестве. Разглядим, к примеру, программу с таковой структурой: doSomething; if(condition) { doStuff; } При трансляции этого выражения в код классических процессоров, нереально будет совместить программирование цели перехода по условию с исполнением doSomething.
Возможно с этим совместить вычисление condition, израсходовав на сохранение результата регистр (а регистр как правило весьма жалко, исходя из этого так редко поступают). Но сама команда условной передачи управления может находиться лишь строго по окончании doSomething.До тех пор пока процессор не выполнит doSomething он не должен делать переход.
Современные классические высокопроизводительные процессоры, благодаря своим сложным CU смогут не задерживаться в этом месте, а затевать спекулятивное исполнение перехода, сделав предположение о том, по какой ветви должно идти выполнение. Для этого они пользуются предсказателями переходов, дабы скорее предугадать корректное ветвление.
В то время, когда же условие перехода выясняется вычисленным они смогут сообщить сами себе: о, я красава! не совершил ошибку; либо: капец, капец! я попал не в том направлении, нужно всё переделывать.В MCp же расчёт цели перехода с вышестоящим кодом возможно осуществлять легко, не принуждённо и заблаговременно, в том же параграфе, что и doSomething (само собой разумеется, в случае если зависимости согласно данным это разрешают сделать). Исходя из этого клетки в MCp смогут не недоедать (не испытывать недочёта в руководствах), и обходится наряду с этим без спекулятивного выполнения кода (не тратя на него энергию) и без предсказателя переходов (не тратя на него транзисторы и энергию).
Минус предсказатель перехода без утраты темпа выборки руководств +1 к энергоэффективности.Итак, в MCp вправду имеется распределённый CU, что образуют пара взаимодействующих CU клеток. Вправду эти CU простые, и снабжают совмещённую параллельную обработку: выборки руководств, операций доступа и арифметического счёта к памяти и RF.Трудности роста клетокВот приблизительно такими изюминками владеет MCp.
Потом я попытаюсь возвратиться к началу текста и более обоснованно поведать о заявленных преимуществах. Но прежде необходимо сообщить и о некоторых проблемах, каковые опытные читатели имели возможность уже и сами углядеть. У MCp имеется пара серьёзных неприятностей, одна из которых будет решена в следующих предположениях процессора, а вторая до тех пор пока находится в ходе интенсивного мозгового штурма.Первая неприятность — это обработка прерываний.
До тех пор пока прерывания обрабатываются достаточно грубо по следующему принципу. В случае если при исполнения параграфа не было записей в память, RF и обращений к периферии, то исполнение параграфа останавливается (он как бы и не выполнялся), и управление передаётся в обработчик прерываний. В случае если же одна из таких операций уже была выполнена, то процессор ждёт завершения параграфа и лишь позже передаёт управление обработчику.
Ясно, что для совокупностей настоящего времени это поведение не самое оптимальное (мягко говоря). Но эта неприятность имеет ответ.Во-первых, к периферии, дабы всё трудилось корректно, как правило необходимо обращаться в режиме запрета прерываний. Во-вторых, операции записи возможно накапливать в особом WriteBack-буффере, и затевать настоящее их исполнение по завершении параграфа.
Такая WB-очередь, само собой разумеется, ограниченный ресурс, но так как MCp прекрасно переносит задержки при работе с памятью и RF (да, да, повторюсь, регистры в MCp смогут быть довольно медленными, это, кстати ещё +1 к энергоэффективности), то это не будет громадной проблемой. С таковой очередью прерывания будут обрабатываться без дополнительных непредсказуемых задержек.Вторая неприятность — это устройство управления виртуальной памятью (MMU). С ним до тех пор пока по большому счету ничего не ясно.
С одной стороны, существуют классические OS, каковые хочется: Linux, Plan9 🙂 С другой, наподобие как MMU — это дорогое наслаждение. Считается, что на тестах SPEC на управление MMU тратится 17.5% процессорного времени; а SUN в порыве пропаганды Java на неких нагрузках насчитала аж 40%. С третьей стороны, для чего MMU в управляющих совокупностях и супервычислениях (ближайшие цели для MCp)?
Вычисляем же мы на CUDA без всякой виртуальной памяти. С четвёртой, при созерцании прогресса в области управляемых (надёжных) языков, при росте популярности Java, .Net, JavaScript, Go, появляется вопрос: стоит сосредоточится на помощи таких языков?С пятой стороны, из-за особенности обработки прерываний, в то время, когда точкой отката возможно лишь начало параграфа, смогут покажется неприятности.
Допустим, кэш трансляций (TLB) в MMU будет запланирован на 32 трансляции, а в параграфе будет 33 операции чтения из различных страниц памяти. Таковой параграф нереально будет выполнить. Тут необходимо как-то всё намерено согласовывать и ограничивать.
И т.д. В общем, процесс мозгового штурма этого куба в самом разгаре.Обоснование преимуществ MCpДавайте, наконец, я скоро пройдусь по заявленным в начале статьи пунктам.Энергоэффективностью я Вам уже надоел, возможно 🙂 Но повторюсь, проистекает она из возможности параллельного выполнения кода с хорошим темпом его выборки при помощи несложного распределённого CU. Также, архитектура разрешает ещё и выбирать сценарии работы.
Допустим, к примеру, что совокупность решила о том, что она может поработать в режиме малой производительности и с пониженным энергопотреблением. Тогда она может выбрать одну клетку, сказать ей, что сейчас для эта клетка обязана выбирать N*k+n (k = 0, 1, …) инструкции с N=1 и n=0, а остальные клетки отключить. Затем, всё тот же код будет выполняться одной клеткой.
Profit? PROFIT! И никакого big.LITTLE не требуется.Совершенно верно тем же механизмом возможно обеспечена постепенная деградация.
В случае если при исполнении некоего параграфа обнаружится, что какая-то клетка сломалась, то оставшиеся в живых клетки нужно перепрограммировать, поменяв у каждой N и n. По окончании чего возможно пробовать продолжить вычисление (которое, конечно же, должно начать рассылать всем SMS-ки о том, что беда! беда!).В управляемых средах (managed runtimes) довольно часто необходимо контролировать поведение кода по ходу его исполнения. Потому что не всегда возможно обеспечивать корректность программы одним только статическим анализом (теоретически, само собой разумеется, быть может, но на практике как компилятору проверить что некая зубодробительная физмат функция владеет определёнными особенностями?).
Особенности передачи управления в архитектуре MCp разрешают такие проверки (к примеру, выходов за границы массивов) и программирование передачи управления на обработчик необыкновенных обстановок подмешивать в параграфы, делающие и нужные вычисления. В классических архитектурах так перемешивать код запрещено, по причине того, что инструкция передачи управления обязана находиться где-то перед кодом, корректность которого проверяется.Поклонники функционального программирования должны порадоваться тому, что инструкции в MCp являются не операторами с побочными эффектами, а чистыми операциями, с результатом, зависящим лишь от операндов.
Это, к примеру, облегчает верификацию кода, что принципиально важно для важных (dependable) приложений. Помимо этого, благодаря всё той же особенности ветвлений любимый всеми pattern-matching может выполнятся действеннее. К примеру, делая код (что-нибудь хорошее):fib :: (Integral t) = t — t fib 0 = 1 fib 1 = 1 fib n = fib (n — 1) + как следует (n — 2) CPU с классической архитектурой будет сперва контролировать равенство довода fib на ноль, и ветвится в соответсвии с этим, позже на 1 и т.д.
Навороченный суперскаляр с дополнительным выполнением попытается сделать последующие за первой проверки в спекулятивном режиме, но на это он израсходует собственные внутренние буферы и энергию. А MCp все три проверки может осуществлять параллельно при исполнении одного параграфа, очень не напрягаясь и экономя Ваше электричество.Наконец, аппаратные и масштабирование нити.
Метод выборки руководств, выбора результатов и распространения расчёта готовой к исполнению команды жёстко не привязан к количеству клеток. Клеток возможно столько, сколько разрешает разработка изготовления процессора (какое количество транзисторов влезет, протяженность проводов и т.д.).
Разработчики пробовали моделировать процессор с 16-ю клетками на неком навороченном промышленном софте, что, как полагают, точно отвечает на вопрос: возможно ли таковой процессор соорудить в действительности и будет ли он трудиться на заданной частоте? Ответ был хорошим (громадных подробностей я не знаю). Но ясно, что в самой архитектуре особенных ограничений нет.
И масштабирование такое, повторюсь, не требует трансформации архитектуры клетки.Нити также легко вписываются в протоколы и алгоритмы работы вести войну. Чтобы мультиклеточный процессор поддерживал исполнение нескольких нитей нужно размножить регистровые файлы (для будущих предположений буферы, накапливающие операции записи) и счётчики руководств, а каждому тэгу значения в коммутаторе приписывать идентификатор нити. Больше ничего не требуется.
Наряду с этим возможно легко регулировать количество клеток, каковые делают нить, перепрограммируя упомянутые счётчики.Букв было большое количество, благодарю за внимание!Надеюсь, данный объёмный (уж простите, меньше не вышло) текст окажет помощь мне поделить с кем-нибудь то наслаждение, которое я приобретаю трудясь с этим процессором.
Случайная статья:
- Всему свое время: 10 интересных моделей наручных geek-часов за последние 10 лет
- Чёрная пятница начнётся в четверг: айпад за полцены и не только
Хвост феи — \
Похожие статьи:
-
Мультиклеточный процессор — это что?
Многие слышали о мультиклеточной архитектуре, процессорах а также первых устройствах на них. Особенно продвинутые пользователи опробовали собственные…
-
Умная netatmo welcome camera. узнает тебя из тысячи*
Приветствуем вас в блоге iCover. Чтобы выяснить, на какие конкретно обороты вышел сейчас технический прогресс, нам стоит только окунуться в недалекое…
-
Стабилизация видеосъёмки в киноиндустрии, или «про тульскую головку»
По окончании выхода на экраны русских кинотеатров эпического «Mad Max» на разных ресурсах рунета (и на Хабре Гиктаймсе, а также) начали появляться статьи…