Путаница между временной и пространственной локализацией в коде реальной жизни

Я читал этот вопрос и хотел узнать больше о коде что он показал т.е.

for(i = 0; i < 20; i++)
    for(j = 0; j < 10; j++)
        a[i] = a[i]*j;

Вопросы таковы,

  1. Я понимаю временную локальность, я думаю, что ссылки на i и j должны быть временной локальностью. Я прав?
  2. Я также понимаю пространственную локальность, поскольку вопрос, который я связал, отвечает на то, что ссылки на a[i] должны быть пространственной локальностью. Я прав?
  3. #P3# <блочная цитата> #P4# #P5#

person Community    schedule 18.10.2011    source источник


Ответы (4)


Во-первых, ссылки на var могут быть локальными во времени или локальными в пространстве, а не локальными во времени, что является неправильной грамматикой. Незначительный момент.

Теперь к вашим вопросам.

  1. Принцип Местность во времени гласит, что две инструкции ссылаются на одно и то же место в пределах относительно короткого промежутка времени. Например, в приведенном коде часто упоминается a[i], а такие инструкции, как a[i] = a[i] * 2 и a[i] = a[i] * 3, выполняются очень близко друг к другу. Если мы посмотрим на эту область, мы можем сказать, что ссылки на j и a[i] являются локальными во времени. Ссылки на i также локальны во времени, потому что i упоминается каждый раз, когда есть a[i]. Однако если последняя строка данного кода читается как a[j] = a[j] * j, то ссылки на i не будут локальными во времени, по крайней мере, в рамках внутреннего цикла[1].

  2. Принцип пространственной локальности гласит, что две инструкции ссылаются на смежные области памяти. Ссылки на a[i] являются хорошим примером этого, так как можно предположить (в большинстве случаев), что a[0] и a[1] будут в памяти рядом друг с другом.

  3. Первые два в основном охватывают это, но цитируемый текст верен, и код также демонстрирует пространственную локальность.

[1] - Как правило, когда вы говорите о локальности, это будет в контексте данного уровня в иерархии памяти, будь то ОЗУ, кэш L1 или что-то еще. Во всех смыслах, кроме самого ограниченного, ссылки как на i, так и на j являются локальными во времени.

person brc    schedule 18.10.2011
comment
Спасибо за ответ. Не могли бы вы прояснить мои понятия о переменных и локальности. Переменная j будет увеличиваться каждый раз, когда выполняется внутренний цикл, и будет получать новое значение. Получение нового значения НЕ является пространственной локальностью (даже если оно каждый раз увеличивается на 1)? - person ; 18.10.2011
comment
@Akito правильно, пространственная локализация может возникать только между двумя разными местами в памяти. Поскольку j каждый раз ссылается на одно и то же место, ссылки на j не являются пространственно локальными. - person brc; 18.10.2011
comment
Не могли бы вы также уточнить используемые ссылки на термины. Что это обозначает? - person ; 18.10.2011
comment
Ссылка на такую ​​переменную, как j, просто означает, что значение j доступно или изменено. Таким образом, a[i] является ссылкой как на значение i, так и на все, что хранится в a[i]. - person brc; 18.10.2011

Написание этого ответа, поскольку я не получил его даже после прочтения других ответов на этот вопрос, нескольких других вопросов и википедии (это более запутанно).

Я думаю, что мы тратим много времени и энергии, чтобы понять терминологию, которая в данном случае немного запутанна/сложна. Мне было легче понять, когда я не обращал внимания на термины «пространственный» и «временной».

Начнем с основ.

Давайте попробуем понять, что такое кэш — место, доступ к которому осуществляется быстрее, чем к основной памяти. Это классно. Но это место ограничено и дорого, поэтому нужно использовать его с умом. Но как бы вы (или ОС) решили, что помещать в кеш, а что нет? Должен быть какой-то способ узнать, что нам понадобится в будущем… ах, предсказания будущего! (Отчет меньшинства! Звоните в колокольчики?).

Должен быть какой-то способ определить, что понадобится программе в будущем. Используя здравый смысл и код, мы можем сказать, что некоторые части кода повторяются по своей природе — например, циклы! Если внутри цикла есть переменная i, вы знаете, что в ближайшем будущем к ней будут обращаться снова и снова. Это принцип временной локальности. я могу быть внесен в кеш, так как он временно локальный.

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

Концепция локальности в основном состоит в том, чтобы идентифицировать данные и инструкции для внесения в кеш, чтобы мы могли уменьшить количество промахов в кеше и эффективно использовать это особое место.

person Saurabh Patil    schedule 21.07.2018
comment
Кстати, есть 2 способа воспользоваться преимуществами пространственной локальности: 1) строки кэша содержат несколько элементов, поэтому выполнение 1 запроса загружает кеш для ближайших запросов. 2) предварительная выборка: определение шаблона последовательного доступа и начало загрузки строк кэша, которые потребуются в ближайшее время, прежде чем возникнет промах запроса. ЦП имеют аппаратную логику предварительной выборки для своих кэшей L1/L2/L3. Программные кэши (например, дисковые кэши, управляемые ОС) нуждаются в логике предварительной выборки в программном обеспечении. - person Peter Cordes; 22.07.2018
comment
@PeterCordes: Спасибо за эти баллы. 1. Не понял, что вы имеете в виду под строками кеша, содержащими несколько строк - я должен упустить что-то основное, пожалуйста, уточните, я не прошел курс микропроцессора во время выпуска :) 2. Таким образом, кеши L1/L2/L3 не являются ОС удалось? - person Saurabh Patil; 12.12.2018
comment
Несколько элементов, например. 16 int размером в слово в 64-байтовой строке кэша. И нет, кэши ЦП не управляются ОС. Запрос кеша — это инструкция загрузки или сохранения, а промахи кеша слишком часты, чтобы обрабатывать промахи в программном обеспечении даже только для L3. Согласованные общие кэши важны для эффективного взаимодействия нескольких ядер, поэтому вам действительно нужно аппаратное обеспечение для реализации когерентности кэша MESI. - person Peter Cordes; 12.12.2018
comment
Несколько предметов (и инструкции, я думаю?). Понятно. Возвращаясь к пространственной локализации, предполагаете ли вы в своем пункте 1, что принятие решений происходит на уровне линии, а не на уровне элемента? И следующие загруженные элементы будут следующими инструкциями по умолчанию без какого-либо реального принятия решений (процессором/аппаратом)? - person Saurabh Patil; 12.12.2018

Внешняя петля является примером пространственной локализации. Он последовательно увеличивает адрес, который вызывает внутренний цикл for.

Внутренняя петля демонстрирует временную локальность. К одному и тому же адресу памяти обращаются десять раз подряд и каждый раз умножают на j.

Что касается ваших первых двух вопросов, то и i, и j (счетчики циклов) являются очень хорошими примерами временной локальности.

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

person Steve Barna    schedule 18.10.2011

Давайте начнем с определения как временной, так и пространственной локализации.

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

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

sum = 0;
for (i = 0; i < arr.length; i++)
  sum += arr[i];
return sum;

Теперь, глядя на этот пример, здесь переменная sum используется снова и снова, что показывает временную местность, а затем значения массива arr доступны в порядке, т.е. arr[0], arr[1], arr [2] ,... и т. д., и который показывает Пространственное местоположение, так как массивы являются непрерывными (смежными) блоками памяти, поэтому данные извлекаются рядом с текущим местоположением памяти.

Теперь, глядя на этот пример

for(i = 0; i < 20; i++)
    for(j = 0; j < 10; j++)
        a[i] = a[i]*j;

Здесь мы видим временную локальность, поскольку a[i] во втором цикле используется снова и снова, а затем доступ к переменной j осуществляется в порядке, который показывает пространственную локальность.

person Shubham Jain    schedule 15.02.2019
comment
В вашем втором примере j является скаляром, поэтому все j доступны сразу. Это временная локализация для a[i] и j во внутреннем цикле. (Конечно, любой приличный компилятор будет хранить их в регистрах для внутреннего цикла, а не сохранять/перезагружать, если вы не отключите оптимизацию. Но, по-видимому, вы имеете в виду псевдокод для ассемблера, а не настоящий C для компиляции с оптимизирующим компилятором. Потому что хороший компилятор полностью развернет внутренний цикл и превратит его в a[i] *= 0*1*2*3*4*5*6*7*8*9, т.е. умножит a[i] на константу времени компиляции.) На самом деле просто a[i] = 0, потому что вы включаете 0 в качестве множителя. - person Peter Cordes; 15.02.2019