Почему существуют отдельные кэши L1 для данных и инструкций?
23
Просто просмотрел несколько слайдов и заметил, что кэш L1 (по крайней мере, на процессорах Intel) различает кэш данных и инструкций. Я хотел бы знать, почему это так.
Во-первых, и, вероятно, прежде всего, данные, которые хранятся в кеше команд, обычно несколько отличаются от тех, которые хранятся в кеше данных - наряду с самими инструкциями существуют аннотации для таких вещей, как начало следующей инструкции, для помощи декодерам. Некоторые процессоры (например, Netburst, некоторые SPARC) используют «кэш трассировки», в котором хранится результат декодирования команды, а не сохраняется исходная команда в ее закодированной форме.
Во-вторых, это немного упрощает схемы - кэш данных имеет дело с чтением и записью, а кэш инструкций имеет дело только с чтением. (Это часть того, почему самоизменяющийся код стоит так дорого - вместо прямой перезаписи данных в кеше команд, запись проходит через кеш данных в кэш L2, а затем строка в кеше команд становится недействительной и перезаписывается. загружен из L2).
В-третьих, это увеличивает пропускную способность: большинство современных процессоров могут одновременно считывать данные из кэша команд и кэша данных. У большинства также есть очереди на «входе» в кеш, поэтому они могут фактически выполнить две операции чтения и одну запись в любом заданном цикле.
В-четвертых, это может сэкономить энергию. Хотя вам необходимо поддерживать питание самих ячеек памяти, чтобы поддерживать их содержимое, некоторые процессоры могут отключать некоторые связанные схемы (декодеры и тому подобное), когда они не используются. С помощью отдельных кешей они могут включать эти схемы отдельно для получения инструкций и данных, что увеличивает вероятность того, что цепь останется отключенной в течение любого заданного цикла (я не уверен, что это делают какие-либо процессоры x86 - AFAIK, это больше ARM вещь).
Также важно упомянуть, что код и данные могут демонстрировать разные шаблоны доступа; например, инструкции для суммирования всех элементов в массиве показывают временную локализацию (одни и те же инструкции часто используются (если вы делаете это циклом)), а данные в массиве демонстрируют пространственную локализацию (далее используются следующие данные).
Габлин
1
@gablin: хотя это и правда, эти различия в шаблонах часто бывают в пользу единого кэша. В тесном цикле, как вы упомянули, большая часть кэша команд находится в режиме ожидания. Унифицированный кеш в основном удвоил бы размер кеша данных на время цикла.
Джерри Коффин
Не совсем, потому что после этого маленького цикла есть больше кода, и это также, вероятно, будет работать с массивом. Это характеризует очень много кода (например, обработка строк). Фактически, первые кеши ЦП были унифицированными кешами - они находились между основным интерфейсом памяти ЦП и внешней шиной, что было простым местом для их размещения - но теперь мы используем секционированный кеш, потому что на практике он быстрее .
Донал Феллоуз
@Donal Fellows: Да, действительно. Я хорошо знаю, как было выполнено раннее кэширование и почему они изменились на разделенный кеш.
Джерри Коффин
5
Как и в случае с недвижимостью, использование кэша зависит от трех факторов: местоположения, местоположения, местоположения. Весь смысл наличия кэша состоит в том, что большинство программ демонстрируют шаблоны местоположения: если они обращаются к байту 1111111, то следующий байт, к которому они получат доступ, вероятно, будет 1111110 или 1111112, и не так много байта 9999999. Однако большинство программ будет демонстрировать очень разные образцы местоположения для их инструкций и их данных. Это означает, что вряд ли инструкции и данные смогут эффективно использовать кэш. Потому что инструкции и данные не обязательно находятся рядом друг с другом в памяти. При доступе к данным команда удаляется из кэша, а инструкция по загрузке - данные из кэша.
Ответы:
На самом деле есть несколько причин.
Во-первых, и, вероятно, прежде всего, данные, которые хранятся в кеше команд, обычно несколько отличаются от тех, которые хранятся в кеше данных - наряду с самими инструкциями существуют аннотации для таких вещей, как начало следующей инструкции, для помощи декодерам. Некоторые процессоры (например, Netburst, некоторые SPARC) используют «кэш трассировки», в котором хранится результат декодирования команды, а не сохраняется исходная команда в ее закодированной форме.
Во-вторых, это немного упрощает схемы - кэш данных имеет дело с чтением и записью, а кэш инструкций имеет дело только с чтением. (Это часть того, почему самоизменяющийся код стоит так дорого - вместо прямой перезаписи данных в кеше команд, запись проходит через кеш данных в кэш L2, а затем строка в кеше команд становится недействительной и перезаписывается. загружен из L2).
В-третьих, это увеличивает пропускную способность: большинство современных процессоров могут одновременно считывать данные из кэша команд и кэша данных. У большинства также есть очереди на «входе» в кеш, поэтому они могут фактически выполнить две операции чтения и одну запись в любом заданном цикле.
В-четвертых, это может сэкономить энергию. Хотя вам необходимо поддерживать питание самих ячеек памяти, чтобы поддерживать их содержимое, некоторые процессоры могут отключать некоторые связанные схемы (декодеры и тому подобное), когда они не используются. С помощью отдельных кешей они могут включать эти схемы отдельно для получения инструкций и данных, что увеличивает вероятность того, что цепь останется отключенной в течение любого заданного цикла (я не уверен, что это делают какие-либо процессоры x86 - AFAIK, это больше ARM вещь).
источник
Как и в случае с недвижимостью, использование кэша зависит от трех факторов: местоположения, местоположения, местоположения. Весь смысл наличия кэша состоит в том, что большинство программ демонстрируют шаблоны местоположения: если они обращаются к байту 1111111, то следующий байт, к которому они получат доступ, вероятно, будет 1111110 или 1111112, и не так много байта 9999999. Однако большинство программ будет демонстрировать очень разные образцы местоположения для их инструкций и их данных. Это означает, что вряд ли инструкции и данные смогут эффективно использовать кэш. Потому что инструкции и данные не обязательно находятся рядом друг с другом в памяти. При доступе к данным команда удаляется из кэша, а инструкция по загрузке - данные из кэша.
источник