Я только начинаю работать с процессорами и не могу понять следующее.
Предположим, что у нас есть массив, объявленный как
static double x[1000][3]
что мы получаем доступ к функции
double up (double *a, int i)
{
double t=*(a+i*3);
return t;
}
int main(int argc, char *argv[])
{
static double x[1000][3];
//some manipulations//
double b;
for (int i=0;i<10;i++)
{
b=up(&x[0][0],i);
}
}
В этом случае, что загружается в кэш-память — фактические значения, на которые указывает указатель или только адреса? Если адреса — значит ли это, что будет еще один цикл для загрузки фактических значений? Это в целом хорошо для использования кэша в отношении этого цикла?
Точный ответ зависит от платформы, но, вообще говоря, три вещи вызывают загрузку данных из внешней памяти в кэш процессора.
Наиболее очевидной является действительная инструкция, которая обращается к памяти обычным способом. Если этот адрес памяти не находится в кэше процессора, процессор должен будет его получить. Второй способ — умозрительная предварительная выборка. Некоторые процессоры получают память в кэш, если они считают, что код может получить к ней доступ. Наконец, компиляторы могут фактически выдавать инструкции для помещения вещей в кеш.
Все ваши операции с указателями, так что это все, что они будут загружать, кроме этого: double t=*(a+i*3);
, Это фактически разыменовывает указатель и обращается к его значению. Поэтому, если компилятор не достаточно умен, чтобы оптимизировать удаленный доступ (потому что вы никогда не используете результат), который, вероятно, является единственной частью вашего кода, которая приведет к чему-то другому, кроме указателя, читаемого из основной памяти в кэш. (Предполагается, что он когда-нибудь попадет в основную память, что зависит от размера вашего кэша.)