Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Boroda_2

.doc
Скачиваний:
7
Добавлен:
20.03.2015
Размер:
1.67 Mб
Скачать

А теперь вернемся к циклу 2. Мы можем разбить микрокоманду swap2 на мик­рошаги и начать их выполнение. В цикле 2 мы копируем значение SP в регистр В, затем пропускаем значение через АЛУ в цикле 3 и, наконец, сохраняем его в регистре MAR в цикле 4. Пока все хорошо. Должно быть ясно, что, если мы сможем начинать новую микрокоманду в каждом цикле, скорость работы маши­ны увеличится в три раза. Такое повышение скорости происходит за счет того, что машина Mic-З производит в три раза больше циклов в секунду, чем Mic-2. Фактически мы построили конвейерный процессор.

К сожалению, мы наткнулись на преграду в цикле 3. Прекрасно было бы на­чать микрокоманду swap3, но эта микрокоманда сначала пропускает значение MDR через АЛУ, а значение MDR не может быть получено из памяти до начала цик­ла 5. Ситуация, когда следующий микрошаг не может начаться, потому что пе­ред этим нужно получить результат выполнения предыдущего микрошага, назы­вается реальной взаимозависимостью, или RAW-взаимозависимостью (Read After Write — чтение после записи). Взаимозависимости иногда называют рисками.

В такой ситуации требуется считать значение регистра, которое еще не записано. Единственное разумное решение в данном случае — отложить начало микроко­манды swap3 до того момента, когда значение MDR станет доступным, то есть до пятого цикла. Ожидание нужного значения называется простоем. После этого мы можем начинать выполнение микрокоманд в каждом цикле, поскольку таких ситуаций больше не возникает, хотя имеется пограничная ситуация: микроко­манда swap6 считывает значение регистра Н в цикле, который следует сразу по­сле записи этого регистра в микрокоманде swap3. Если бы значение этого регист­ра считывалось в микрокоманде swap5, машине пришлось бы простаивать один цикл.

Хотя программа Mic-З требует больше циклов, чем программа Mic-2, она ра­ботает гораздо быстрее. Если время цикла микроархитектуры Mic-З составляет АТ не, то для выполнения команды SWAP машине Mic-З требуется 11 АТ не, а ма­шине Mic-2 — 6 циклов по ЗДТ не каждый, то есть всего 18АТ не. Конвейериза­ция увеличивает быстродействие компьютера даже несмотря на то, что один раз приходится простаивать из-за явления реальной взаимозависимости.

Конвейеризация является ключевой технологией во всех современных про­цессорах, поэтому важно хорошо в ней разбираться. На рис. 4.22 графически проиллюстрирована конвейеризация тракта данных, изображенного на рис. 4.21. В первой колонке показано, что происходит во время цикла 1, вторая колонка представляет цикл 2 и т. д. (предполагается, что простоев нет). Закрашенная об­ласть на рисунке для цикла 1 и команды 1 означает, что блок выборки команд за­нят вызовом команды 1. В цикле 2 значения регистров, вызванных командой 1, загружаются в А и В, а в это время блок выборки команд занимается вызовом команды 2, что также показано закрашенными серыми прямоугольниками.

Во время цикла 3 команда 1 использует АЛУ и схему сдвига, регистры А и В загружаются для команды 2, вызывается команда 3. Наконец, во время цикла 4 работают все 4 команды одновременно. Сохраняются результаты выполнения команды 1, АЛУ выполняет вычисления для команды 2, регистры А и В загру­жаются для команды 3, вызывается команда 4.

Если бы мы показали цикл 5 и следующие, модель была бы точно такой же, как в цикле 4: все четыре части тракта данных работали бы независимо друг от друга. Данный конвейер содержит 4 ступени: для вызова команд, для доступа к операндам, для работы АЛУ и для записи результата обратно в регистры. Он по­хож на конвейер, изображенный на рис. 2.3, а, только у него отсутствует ступень декодирования (расшифровки). Здесь важно подчеркнуть, что, хотя выполнение одной команды занимает 4 цикла, в каждом цикле начинается новая команда и завершается предыдущая.

Можно рассматривать схему на рис. 4.22 не вертикально (по колонкам), а го­ризонтально (по рядам). При выполнении команды 1 в цикле 1 функционирует блок выборки команд. В цикле 2 значения регистров помещаются на шины А и В. В цикле 3 работают АЛУ и схема сдвига. Наконец, в цикле 4 полученные ре­зультаты сохраняются в регистрах. Отметим, что имеется 4 доступных устройст­ва и во время каждого цикла определенная команда использует только одно из них, оставляя свободными другие устройства для других команд.

Проведем аналогию с конвейером на заводе, производящем автомобили. Чтобы изложить суть работы такого конвейера, представим, что ровно каж­дую минуту звучит гонг, и в этот момент все автомобили передвигаются по конвейеру на один шаг. На каждом шаге рабочие выполняют определенную операцию с автомобилем, который оказывается перед ними, например ставят колеса или тормоза. При каждом ударе гонга (это — 1 цикл) очередная заго­товка поступает на конвейер и один собранный автомобиль сходит с конвейе­ра. Таким образом, завод выпускает один автомобиль в минуту независимо от того, сколько времени занимает сборка одного автомобиля. В этом и состоит суть конвейера. Такой подход в равной степени применим и к процессорам, и к автомобилям.

Семиступенчатый конвейер — микроархитектура Mic-4

Мы не упомянули о том факте, что каждая микрокоманда выбирает следующую за ней. Большинство из них просто выбирают очередную команду в текущей по­следовательности, но последняя из них, например swap6, часто совершает меж- уровневый переход, который останавливает работу конвейера, поскольку после этого перехода вызывать команды заранее уже бессмысленно. Поэтому нам нуж­но придумать лучшую технологию.

Следующая (и последняя) микроархитектура — Mic-4. Ее основные компо­ненты представлены на рис. 4.23, но большая их часть не показана, чтобы сде­лать схему более понятной. Как и Mic-З, эта микроархитектура содержит блок выборки команд (IFU), который заранее вызывает слова из памяти и сохраняет различные значения MBR.

Блок выборки команд передает входящий поток байтов в новый компонент — блок декодирования. Этот блок содержит внутреннее ПЗУ, которое индексиру­ется кодом IJVM-операции. Каждый элемент (ряд) блока состоит из двух частей: поля длины IJVM-команды и индекса в другом ПЗУ — ПЗУ микроопераций. Длина IJVM-команды нужна для того, чтобы блок декодирования мог разделить входящий поток байтов и установить, какие байты являются кодами операций, а какие — операндами. Если длина текущей команды составляет 1 байт (напри­мер, длина команды POP), то блок декодирования определяет, что следующий байт — это код операции. Если длина текущей команды составляет 2 байта, блок декодирования определяет, что следующий байт — это операнд, сразу за кото­рым следует другой код операции. Когда появляется префиксная команда WIDE, следующий байт преобразуется в специальный расширенный код операции, на­пример, WIDE плюс IL0AD превращается в WIDE IL0AD.

Блок декодирования передает индекс в ПЗУ микроопераций, который он на­ходит в своей таблице, следующему компоненту, блоку формирования очереди. Этот блок содержит логические схемы и две внутренние таблицы одну для ПЗУ и вторую для ОЗУ. В ПЗУ находится микропрограмма, причем каждая IJVM-ко­манда состоит из микроопераций. Эти микрооперации должны располагаться в строгом порядке, и, например, переход из wide_iload2 в iload2, который допустим в микроархитектуре Mic-2, не разрешается. Каждая последовательность микро­операций должна выполняться полностью, в некоторых случаях последователь­ности дублируются.

Структура микрооперации сходна со структурой микрокоманды (см. рис. 4.4), только в данном случае поля NEXT_ADDRESS и JAM отсутствуют и требуется новое поле для определения входа на шину А. Имеется также два новых бита: бит завершения и бит перехода. Бит завершения устанавливается на последней микрооперации каждой последовательности (чтобы обозначить эту операцию). Бит перехода нужен для указания на микрооперации, которые являются услов­ными микропереходами. По формату они отличаются от обычных микроопера­ций. Они состоят из битов JAM и индекса в ПЗУ микроопераций. Микрокоманды, которые раньше осуществляли какие-либо действия с трактом данных, а также выполняли условные микропереходы (например, iflt4), теперь нужно разбивать на две микрооперации.

Блок формирования очереди работает следующим образом. Он получает от блока декодирования индекс микрооперации в ПЗУ микроопераций. Затем он отыскивает микрооперацию и копирует ее во внутреннюю очередь. После этого он копирует очередную микрооперацию в ту же очередь, а также микроопера­цию, следующую за этой микрооперацией. Так продолжается до тех пор, пока не появится микрооперация с битом завершения. Тогда блок копирует эту послед­нюю микрооперацию и останавливается. Если блоку не встретилась микроопера­ция с битом перехода и у него осталось достаточно свободного пространства, он посылает сигнал подтверждения приема блоку декодирования. Когда блок деко­дирования принимает сигнал подтверждения, он посылает блоку формирования очереди следующую IJVM-команду.

Таким образом, последовательность IJVM-команд в памяти в конечном итоге превращается в последовательность микроопераций в очереди. Эти микрооперации передаются в регистры MIR, которые посылают сигналы тракту данных. Но есть еще один фактор, который нам нужно учесть: поля каждой микрооперации не действуют одновременно. Поля А и В активны во время первого цикла, поле АЛУ активно во время второго цикла, поле С активно во время третьего цикла, а все операции с памятью происходят в четвертом цикле.

Чтобы все эти операции выполнялись правильно, мы ввели 4 независимых регистра MIR в схему на рис. 4.23. В начале каждого цикла (на рис. 4.2 это вре­мя Aw) значение MIR3 копируется в регистр MIR4, значение MIR2 — в регистр MIR3, значение MIR1 — в регистр MIR2, а в MIR1 загружается новая микроопе­рация из очереди. Затем каждый регистр MIR выдает сигналы управления, но используются только некоторые из них. Поля А и В из регистра MIR1 применя­ются для выбора регистров, которые запускают защелки А и В, а поле АЛУ в ре­гистре MIR1 не используется и не связано ни с чем на тракте данных.

В следующем цикле микрооперация передается в регистр MIR2; выбранные регистры находятся в защелках А и В. Поле АЛУ теперь используется для запус­ка АЛУ. В следующем цикле поле С запишет результаты обратно в регистры. После этого микрооперация передается в регистр MIR4 и инициирует любую не­обходимую операцию памяти, используя загруженное значение регистра MAR (или MDR для записи).

Нужно обсудить еще один аспект микроархитектуры Mic-4 — микроперехо­ды. Некоторым IJVM-командам нужен условный переход, который осуществля­ется с помощью бита N. Когда происходит такой переход, конвейер не может продолжать работу. Именно поэтому нам пришлось добавить в микрооперацию бит перехода. Когда в блок формирования очереди поступает микрооперация с таким битом, блок воздерживается от передачи сигнала о получении данных блоку декодирования. В результате машина простаивает до тех пор, пока этот пе­реход не разрешится.

Предположительно, некоторые IJVM-команды, не зависящие от этого перехо­да, могут быть уже переданы в блок декодирования, но не в блок формирования очереди, поскольку он еще не выдал сигнал о получении. Чтобы разобраться в этой путанице и вернуться к нормальной работе, требуется специальное устрой­ство и особые механизмы, но мы не будем рассматривать их в этой книге. Здесь отметим только, что классик, написавший о губительности команд goto, был без­условно прав [55].

Мы начали с микроархитектуры Mic-1 и, пройдя довольно долгий путь, за­кончили микроархитектурой Mic-4. Аппаратное обеспечение микроархитектуры Mic-1 оказалось очень простым, поскольку практически все управление было реализовано программно. Микроархитектура Mic-4 является конвейеризирован­ной структурой с семью ступенями и более сложным аппаратным обеспечением. Данный конвейер изображен на рис. 4.24. Цифры в кружочках соответствуют компонентам на рис. 4.23. В микроархитектуре Mic-4 поток байтов заранее вы­зывается из памяти в автоматическом режиме, декодируется в IJVM-команды, которые затем с помощью ПЗУ превращаются в последовательность операций и применяются по назначению. Первые три ступени конвейера при желании мож­но связать с задающим генератором тракта данных, но работа будет происходить не в каждом цикле. Например, блок выборки команд совершенно точно не смо­жет передавать новый код операции блоку декодирования в каждом цикле, по­скольку выполнение IJVM-команды занимает несколько циклов и очередь бы­стро переполнится.

0 © © ® © © ®

В каждом цикле значения регистров MIR смещаются, и микрооперация, на­ходящаяся в начале очереди, копируется в регистр MIR1. Затем сигналы управ­ления от всех четырех регистров MIR передаются по тракту данных, вызывая определенные действия. Каждый регистр MIR контролирует отдельную часть тракта данных и, следовательно, разные микрошаги.

В данной разработке имеется конвейеризированный процессор. Благодаря этому отдельные шаги становятся очень короткими, а тактовая частота — высо­кой. Многие процессоры проектируются именно таким образом, особенно те, ко­торым приходится выполнять устаревший набор команд (CISC). Например, процессор Pentium II в некоторых аспектах сходен с микроархитектурой Mic-4, как мы увидим позднее в этой главе.

Повышение производительности

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

Рассматриваемые усовершенствования можно разделить на две категории, касающиеся реализации и архитектуры. Усовершенствования реализации — это такие способы построения новых процессора и памяти, после применения кото­рых система работает быстрее, но архитектура при этом не меняется. Изменение реализации без изменения архитектуры означает, что устаревшие программы смо­гут работать на новой машине, а это очень важно для успешной продажи. Чтобы усовершенствовать реализацию, можно, например, использовать более быстрый задающий генератор, но это — не единственный способ. Отметим, что рост про­изводительности от процессора 80386 к процессорам 80486, Pentium, Pentium Pro, а затем и к Pentium II, достигался без изменения архитектуры.

Однако некоторые варианты усовершенствований можно реализовать только путем изменения архитектуры. Иногда, например, нужно добавить новые команды или регистры, причем таким образом, чтобы устаревшие программы могли рабо­тать на новых моделях. В этом случае для достижения максимальной производи­тельности программное обеспечение приходится переделывать или, по крайней мере, заново компилировать на новом компиляторе.

Однако один раз в несколько десятилетий разработчики понимают, что ста­рая архитектура уже никуда не годится и единственный способ развивать техно­логии дальше — начать все заново. Таким революционным скачком было появ­ление в 80-х годах RISC-архитектуры, а сейчас уже приближается следующий прорыв. Мы рассмотрим соответствующий пример (Intel IA-64) в главе 5.

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

Кэш-память

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

Современные процессоры предъявляют определенные требования к системе памяти и в плане времени ожидания (задержки в доставке операнда), и в плане пропускной способности (объему данных, передаваемых в единицу времени). К сожалению, эти два аспекта системы памяти в значительной степени противо­речивы. Обычно с повышением пропускной способности увеличивается время ожидания. Например, конвейерные технологии, которые мы использовали в микроархитектуре Mic-З, можно применить и к системе памяти, в этом случае запросы к памяти будут обрабатываться более рационально, с перекрытием. Од­нако, к сожалению, как и в микроархитектуре Mic-З, это приводит к увеличению времени ожидания отдельных операций памяти. С увеличением скорости рабо­ты задающего генератора становится все сложнее поддерживать такую систему памяти, которая могла бы передавать операнды за один или два цикла.

Один из вариантов решения проблемы — добавление кэш-памяти. Как мы отме­чали в подразделе «Кэш-память» раздела «Основная память» главы 2, в кэш-па­мяти хранятся наиболее часто используемые слова, за счет чего повышается ско­рость доступа к ним. Если достаточно большой процент нужных слов находится в кэш-памяти, время ожидания может значительно сократиться.

Одной из самых эффективных технологий одновременного увеличения про­пускной способности и уменьшения времени ожидания является применение нескольких блоков кэш-памяти. Основной прием — введение отдельных кэшей для команд и данных (так называемая разделенная кэш-память). Такая кэш-па­мять имеет несколько преимуществ, в частности, операции могут начинаться не­зависимо в каждой кэш-памяти, что удваивает пропускную способность системы памяти. Именно по этой причине в микроархитектуре Mic-1 нам понадобились два отдельных порта памяти: отдельный порт для каждого кэша. Отметим, что каждый кэш имеет независимый доступ к основной памяти.

В настоящее время многие системы памяти гораздо сложнее этих. Между раз­деленной кэш-памятью и основной памятью часто помещается кэш-память вто­рого уровня. Вообще говоря, поскольку требуются более совершенные системы, может быть три и более уровня кэш-памяти. На рис. 4.25 изображена система с тремя уровнями кэш-памяти. Прямо на микросхеме центрального процессора находится небольшой кэш для команд (L1-I) и небольшой кэш для данных (L1-D) объемом обычно от 16 до 64 Кбайт. Есть еще кэш-память второго уровня (L2), которая расположена не на самой микросхеме процессора, а рядом с ним в том же блоке. Кэш-память второго уровня соединяется с процессором через вы­сокоскоростной тракт данных. Эта кэш-память обычно не является разделенной и объединяет данные и команды. Ее размер — от 512 Кбайт до 1 Мбайт. Кэш-па­мять третьего уровня (L3) находится на той же плате, что и процессор, и обычно состоит из статического ОЗУ в несколько мегабайтов, которое функционирует гораздо быстрее, чем динамическое ОЗУ основной памяти. Как правило, все со­держимое кэш-памяти первого уровня находится в кэш-памяти второго уровня, а все содержимое кэш-памяти второго уровня — в кэш-памяти третьего уровня.

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

Во всех типах кэш-памяти используется следующая модель. Основная память разделяется на блоки фиксированного размера, которые называются строками кэша. Строка кэша состоит из нескольких последовательных байтов (обычно от 4 до 64). Строки нумеруются, начиная с 0, то есть если размер строки составляет 32 байта, то строка 0 — это байты с 0 по 31-й, строка 1 — байты с 32-го по 63-й и т. д. В любой момент в кэш-памяти находится несколько строк. Когда происхо­дит обращение к памяти, контроллер кэш-памяти проверяет, есть ли нужное сло­во в кэш-памяти. Если слово есть (случай кэш-попадания), то можно сэкономить время, требуемое на доступ к основной памяти. Если данного слова в кэш-памя­ти нет (случай кэш-промаха), то одна из строк из кэша удаляется, а вместо нее туда помещается запрошенная строка из основной памяти или из кэш-памяти более низкого уровня. Существует множество вариаций данной схемы, но в их основе всегда лежит идея держать в кэш-памяти как можно больше часто ис­пользуемых строк, чтобы число кэш-попаданий было максимальным.

Кэш-память прямого отображения

Самый простой тип кэш-памяти — кэш-память прямого отображения. Пример одноуровневой кэш-памяти прямого отображения показан на рис. 4.26, а. Данная кэш-память содержит 2048 элементов. Каждый элемент (ряд) может вмещать ровно одну сроку из основной памяти. Если размер строки кэша составляет 32 байта (как в этом примере), кэш-память может вмещать 64 Кбайт. Каждый элемент кэш-памяти состоит из трех частей:

+ Бит достоверности указывает, есть достоверные данные в элементе или нет. Когда система загружается, все элементы маркируются как недостоверные.

+ Поле тега состоит из уникального 16-разрядного значения, указывающего соответствующую строку памяти, из которой поступили данные.

+ Поле данных содержит копию данных памяти. Это поле вмещает одну строку кэша размером 32 байта.

В кэш-памяти прямого отображения заданное слово может храниться только в одном месте. Если его в этом месте нет, значит, его вообще нет в кэш-памяти. Для хранения данных в кэше и извлечения их из кэша адрес разбивается на 4 компонента, как показано на рис. 4.26, б\

+ Поле строки указывает, какой элемент кэш-памяти содержит соответст­вующие данные, если они есть в кэш-памяти.

б

Рис. 4.26. Кэш-память прямого отображения (а); 32-разрядный виртуальный адрес (б)

+ Поле тега соответствует битам, сохраненным в поле тега элемента кэш-па­мяти.

♦ Поле слова указывает, на какое слово в строке производится ссылка.

+ Поле байта обычно не используется, но если требуется только один байт, в этом поле указано, какой именно байт в слове нужен. Для кэш-памяти, поддерживающей только 32-разрядные слова, это поле всегда содержит 0.

Когда центральный процессор выдает адрес памяти, аппаратура выделяет из этого адреса 11 бит поля строки и использует их для поиска в кэш-памяти одно­го из 2048 элементов. Если элемент действителен, то производится сравнение поля тега основной памяти и поля тега кэш-памяти. Если поля равны, значит, в кэш-памяти есть запрашиваемое слово. Такая ситуация называется кэш-попа- данием. В случае кэш-попадания слово берется прямо из кэш-памяти, и тогда не нужно обращаться к основной памяти. Из элемента кэш-памяти берется только нужное слово, остальная часть элемента не используется. Если элемент кэш-па- мяти недействителен (недостоверен) или поля тега не совпадают, то нужного слова нет в памяти. Такая ситуация называется кэш-промахом. В этом случае 32-байтная строка вызывается из основной памяти и сохраняется в кэш-памяти, заменяя тот элемент, который там был. Однако если существующий элемент кэш-памяти изменяется, его нужно записать обратно в основную память до того, как он будет удален.

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

При такой схеме смежные строки основной памяти помещаются в смежные элементы кэш-памяти. Фактически в кэш-памяти может храниться до 64 Кбайт смежных данных. Однако две строки, адреса которых отличаются ровно на 64 Кбайт (65 536 байт) или на любое целое, кратное этому числу, не могут одно­временно хранится в кэш-памяти (поскольку они имеют одно и то же значение поля строки). Например, если программа обращается к данным с адресом X, а за­тем выполняет команду, которой требуются данные с адресом X + 65 536 (или с любым другим адресом в той же строке), вторая команда требует перезагрузки элемента кэш-памяти. Если это происходит достаточно часто, то могут возник­нуть проблемы. В действительности, если кэш-память плохо работает, лучше, чтобы ее вообще не было, поскольку при каждой операции с основной памятью считывается целая строка, а не одно слово.

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

Ассоциативная кэш-память с множественным доступом

Как было отмечено ранее, различные строки основной памяти конкурируют за право занять одну и ту же область кэша. Если программе, использующей кэш-па- мять, изображенную на рис. 4.26, а, часто требуются слова с адресами 0 и 65 536, то будут иметь место постоянные конфликты, поскольку каждое обращение по­тенциально повлечет за собой вытеснение из кэш-памяти той или иной строки. Чтобы разрешить эту проблему, нужно сделать так, чтобы в каждом элементе кэш-памяти помещалось по две и более строки. Кэш-память с п возможными элементами для каждого адреса называется n-входовой ассоциативной кэш-па- мятью. 4-входовая ассоциативная кэш-память изображена на рис. 4.27.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]