Здесь мы подошли к фундаментальной концепции микроархитектуры К7/К8. Мы уже видели, что объединение двух отдельных микроопераций в одну макрооперацию даёт явные преимущества. Точно также дела обстоят и с самими макрооперациями — практически везде они выступают не в виде самостоятельных единиц, а в виде группы. Группу образуют как раз те 3 mOP-а, которые одновременно запускаются на параллельные каналы. Вся дальнейшая работа идет не с одиночными mOP-ами, а с «тройками» mOP-ов («line»). Такая тройка mOP-ов, «line», с точки зрения центрального управляющего блока процессора, ICU (Instruction Control Unit) воспринимается как единое целое: все основные действия выполняются именно над «line», в первую очередь — выделение внутренних ресурсов. Так, под «line» одним приемом выделяется группа из трех позиций в очередях (как мы помним, у каждого канала своя очередь). Здесь mOP-ы на короткое время приобретает независимость — точнее, самостоятельными оказываются ROP-ы, которые выбираются для запуска на ФУ в наилучшей последовательности. Когда окажутся запущенными составляющие всех трех mOP-ов, относящихся к «line», соответствующие позиции в очередях будут одновременно освобождены. Точно также, одновременно будет происходить и «отставка» — освобождение ресурсов после исполнения, сопровождающееся окончательной записью результатов в регистровый файл.
Этот дизайн сама AMD характеризует как «line-oriented», и он является предметом законной гордости корпорации. В нем каждый конвейер представляет собой один «канал» — кстати сказать, слово «канал» не является точной терминологией. Похоже, в этом случае жестко закрепленного термина вовсе не вводится, каждый раз, в зависимости от контекста, применяются термины «position», «issue position», «lane».
Итак, мы имеем три симметричных канала, работающих синхронно и параллельно. Макрооперации проходят конвейер, оставаясь прикрепленными к своим каналам — таким образом практически исключаются поздние стадии переброски и распределения команд по тем портам, к которым подсоединены специфические функциональные устройства, необходимые для исполнения конкретной команды (как правило — это самый «горячий» участок процессора). Далее, «line-oriented» подход позволяет кардинально снизить количество управляющей логики и количество «контролируемых элементов». Использование макроопераций, а не ROP-ов, в качестве элементов «line» позволяет увеличить её эффективную ширину, то есть, в конечном счете — количество команд, обрабатываемых за один такт. Наконец, количество параллельно обрабатываемых элементов в дальнейшем без особых сложностей может быть расширено просто за счет увеличения числа каналов (и, соответственно, количества ФУ). И, последнее: важно отметить, что хотя основные концепции и направлены на построение «широкого» эффективного конвейера, с равным успехом они могут быть применены к конвейерам самой разной длины.
И в этом моменте становится заметным ключевое отличие концепции К7 от концепции Pentium 4: если Pentium 4 спроектирован на достижение максимальной частоты, то К7 (да и К8, вообще говоря) в первую очередь рассчитан на исполнение максимального количества mOP-ов за такт (в конечном итоге, большее количество исполненных mOP-ов означает большее количество исполненных х86-команд, хотя зависимость здесь нелинейная).
Чтобы проиллюстрировать ситуацию, припомним наш конвейер. Представим себе, что мы для увеличения производительности сделали наш конвейер втрое более широким — то есть теперь на нем параллельно собирается три автомобиля. Соответственно, «листики с инструкциями» на конвейере лежат по три, равно как и «детали для сборки». Более того, «детали» теперь на каждое из трех мест можно класть по две! И, наконец, весь процесс укладки деталей производится одновременно одним механизмом, равно, как и готовые автомобили снимаются одновременно по три штуки.
Микроархитектуру Pentium 4 тогда очень условно можно представить как выстроенную в ряд последовательность из нескольких конвейеров разной ширины, между которыми «детали» и «полусобранные конструкции» перебрасываются специальными методами. Впрочем, не будем отвлекаться от основной задачи — тем более, что ситуация с Pentium 4 требует особого рассмотрения, да и не он является героем сегодняшнего рассказа.
Собственно, вот мы и пришли к идеологии микроархитектуры К7/К8. Надо отдать должное инженерам AMD, конструкция получилась элегантная и эффективная, при этом существенно расширена «параллельность» конвейера. Также весьма интересно, что концепция позволяет рост как «вширь», так и «вглубь».
Теперь понятно, что даже сходным образом звучащая фраза, справедливая для обеих архитектур — в современных процессорах х86-команды превращаются в «RISC-подобные» команды — означает в действительности совершенно разные вещи. Что же, согласитесь, это достаточно интересные сведения, на которых стоило остановиться!
Декодеры и конвейеры, ч.2. К7 и К8.
Здесь мы столкнулись с достаточно сложной ситуацией – т.к. точной информации по работе декодеров, а точнее, пути, который проходит команда, превращаясь в mOPы, просто нет. Есть только несколько общих наметок и результаты синтетических тестов.
Так как общие принципы работы декодеров остались неизменными, мы решили подробно рассмотреть работу декодеров К7 и указать отличия, которые присутствуют в К8 и потдверждены экспериментально или известны из официальных источников.
Прежде всего определимся с терминологией; дело в том, что в архитектуре К7 термин «декодер» употребляется в нескольких контекстах, а именно:
Рассмотрим, как происходит работа декодера и конвейера в К7 (называя попутно этапы конвейера):
Здесь прервемся на секунду, и обратим внимание, что недостаток VectorPath инструкции состоит в том, что она «занимает» все три канала декодирования, не позволяя работать DP декодерам параллельно. Важно отметить, что сама по себе VectorPath инструкция не является «плохой» — Microcode Engine работает с той же скоростью «3 mOP-а в такт», что и DP декодеры, при этом полученные из VectorPath mOP-ы ничем не хуже полученных из DirectPath. Напротив, для сложных инструкций, дающих десятки команд (для деления, или для многих системных инструкций), VectorPath - прекрасное решение! Проблема в VectorPath заключается в побочных эффектах, связанных с положением VP инструкции в «тройке». А именно:
Нетрудно заметить, что, если, например, двух-mOP-овая VP-инструкция в потоке DP-инструкций занимает позицию #