2016-02-15 7 views
0

Если выполняется следующий код:В кэше процессора также загружается информация из предыдущих мест памяти?

int *array = new int[1000]; 
for (int i = 0; i < 1000; i++) 
    array[i] = i * 2; 

магазинов CPU массива в кэше. Но, если выполняется следующий код:

int *array = new int[1000]; 
for (int i = 1000-1; i >= 0; i--) 
    array[i] = i * 2; 

Я интересно, если процессор может также кэшировать массив, или если он только предполагает, что существует в направлении «вперед».

+0

Вам все равно. Исключение для производительности, кэш CPU прозрачен для программ. –

+0

Работа с кешем с строками 32 или 64 и т. Д. (Зависит от оборудования). и, возможно, с гранулярностью памяти, поэтому сначала воспользуйтесь любым блоком памяти байта (n-байтами) в строку кэша – oklas

+1

Если вы поместите 'int array [1000];' он будет в стеке, который является частью памяти, которая повторно используется так много раз, так что это скорее всего в кеше. Если вы беспокоитесь о кеше, не используйте «новый», он, как правило, намного медленнее промаха в кэше. –

ответ

3

Там далеко слишком много процессоров вне там, чтобы сделать общее предположение об этом, но:

Если вы, скажем, на общей архитектуре x86, то, что кэш будет содержать всегда кратны размер кеш-линии, содержащий первый адрес, к которому вы обращались, что привело к пропуску кеша, то же самое для прямого доступа.

В зависимости от того, насколько сложным будет предсказание доступа к памяти, обратный доступ также может быть предварительно запрограммирован; кто делает это предсказание, зависит от вашей архитектуры процессора, фактической реализации ЦП и вашего компилятора. Для компиляторов нередко «знать», какие шаблоны доступа к памяти хорошо работают для данного поколения ЦП и обеспечивают доступ к памяти в этом порядке.

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

Кроме того, поскольку вы, похоже, заботитесь о скорости, вы, как правило, можете оптимизировать свой компилятор. Во многих случаях это приведет к тому, что такие циклы станут «отмененными», и SIMD'ed, даже.

Обратите внимание, что для других архитектур это может работать по-другому: например, есть печально известное семейство процессоров Motorola в середине 90-х годов, которые имели относительно простой модуль генерации адресов, и такие вещи, как доступ к памяти назад, были возможны быстро, если вы (или ваш компилятор C) знал, как сказать ему работать в обратном направлении; тогда появилась возможность «сплавить» загрузку памяти или сохранить ее с любой другой инструкцией CPU, так что в этом случае ваше кэширование будет эффективно доминировать в том, как вы вручную указали шаблоны доступа к памяти.

0

Да, массив будет кэшироваться. Данные берутся в кеш как кратное размеру строки кэша. Например, если размер строки кеша составляет 8 байт, то при первом доступе к ячейке памяти независимо от того, пытаетесь ли вы получить доступ к байту 0 или байт 7, все ячейки памяти от 0 до 8 будут отправлены в кеш.

1

Мне интересно, может ли ЦП также кэшировать массив или если он предполагает, что он существует в «прямом» направлении.

CPU cache Работает в блоке строк кеша (например, 32 слова или байта). См. this. Порядок, в котором вы обращаетесь к вашему массиву (увеличение или уменьшение адресов), не имеет большого значения. Первым доступом к строке кэша будет некоторая ошибка в кеше (как в ваших прямых, так и в обратных сценариях), но не в следующих.

Компилятор может оптимизировать и развернуть цикл и/или испустить PREFETCH машинные инструкции.Возможно, вы, возможно, используете GCC) его __builtin_prefetch (см. this), но это может даже замедлить ваш код, если вы используете его неправильно.

+0

, который, надо подчеркнуть, будет таким же, как с прямым доступом. –

+0

Сам процессор, скорее всего, выдает некоторые из своих собственных предварительных запросов даже без компилятора. Эти потоки в большинстве распространенных процессоров также могут идти в любом направлении – Leeor

0

Кэш-работа с строками 32 или 64 и т. Д. (Зависит от оборудования). и возможно с гранулярностью памяти, поэтому сначала воспользуйтесь любым блоком памяти с байтом полной загрузки (n-байтами) в строку кэша