Снижение производительности кэша из-за физического размещения данных

Каждый адрес памяти «сопоставляется» с собственным кешем, установленным в кеше (ах) ЦПУ, на основе операции по модулю адреса.

Есть ли способ доступа к двум массивам одинакового размера, например так:

int* array1;  //How does the alignment affect the possibility of cache collisions?
int* array2;

for(int i=0; i<array1.size(); i++){
x = array1[i] * array2[i];   //Can these ever not be loaded in cache at same time?
}

может вызвать снижение производительности, потому что элементы в массивах array1 [i] и array2 [i] дают один и тот же результат строки кэша по модулю? Или это действительно увеличит производительность, потому что для получения двух местоположений данных потребуется загрузить только одну строку кэша?

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

(Причиной моего вопроса является то, что я пытаюсь понять, когда возникает проблема производительности из-за выравнивания данных / сопоставления адресов с одной и той же строкой кэша, что приводит к тому, что один из фрагментов данных не сохраняется в кэше)

NB. Возможно, я перепутал кэш терминов «строка» и «набор» — пожалуйста, не стесняйтесь исправлять.

1

Решение

Прямо сейчас ваш код не имеет особого смысла, так как вы не выделяли память для массивов. Указатели — это всего лишь две неинициализированные переменные, стоящие в стеке и указывающие ни на что. Кроме того, указатель на int * на самом деле не имеет size() функция.

Предполагая, что вы исправите все это, если вы делаете выделение, вы можете решить, следует ли размещать данные непрерывно или нет. Вы можете выделить 2 * N целых чисел для одного указателя, а другой указывать на середину этого региона.

Основное соображение здесь заключается в следующем: если массивы достаточно малы, чтобы не охватывать желаемый уровень кэша, их сопоставление будет непрерывным, чтобы избежать необходимости использовать одни и те же наборы кэша между ними. Это может улучшить производительность, поскольку одновременный доступ к одним и тем же наборам часто неоптимален из-за соображений HW.

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

например, если у вас в кэше было 4 набора и 2 пути, и вы пытаетесь отобразить 2 массива по 64 дюйма со смещением выравнивания, вы все равно заполните весь кэш —

          way0        way1
set 0   array1[0]   array2[32]
set 1   array1[16]  array2[48]
set 2   array1[32]  array2[0]
set 3   array1[48]  array2[16]

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

0

Другие решения