это программа на C под Linux / GUN:
#include<stdio.h>
#include<sys/time.h>
#define Max 1024*1024
int main()
{
struct timeval start,end;
long int dis;
int i;
int m=0;
int a[Max];
gettimeofday(&start,NULL);
for(i=0;i<Max;i += 1){
a[Max] *= 3;
}
gettimeofday(&end,NULL);
dis = end.tv_usec - start.tv_usec;
printf("time1: %ld\n",dis);
gettimeofday(&start,NULL);
for(i=0;i<Max;i += 16){
a[Max] *= 3;
}
gettimeofday(&end,NULL);
dis = end.tv_usec - start.tv_usec;
printf("time2: %ld\n",dis);
return 0;
}
выход:
время1: 7074
время2: 234
это большое расстояние
эта программа на Java:
public class Cache1 {
public static void main(String[] args){
int a[] = new int[1024*1024*64];
long time1 = System.currentTimeMillis();
for(int i=0;i<a.length;i++){
a[i] *= 3;
}
long time2 = System.currentTimeMillis();
System.out.println(time2 - time1);
time1 = System.currentTimeMillis();
for(int i=0;i<a.length;i += 16){
a[i] *= 3;
}
time2 = System.currentTimeMillis();
System.out.println(time2 - time1);
}
}
выход:
92
82
это то же самое
с кешем процессора. почему они имеют такую разницу? кэш процессора недопустим в программировании на C?
Я надеюсь, вы понимаете, что разница в единицах времени в этих тестах составляет 10 ^ 3. Код на C на порядок быстрее, чем код Java.
В коде C должно быть a[i]
вместо a[Max]
,
Что касается кеша: поскольку вы обращаетесь только к одной ячейке памяти в вашем C-коде (что вызывает неопределенное поведение), ваш C-тест полностью недействителен.
И даже если бы это было правильно, ваш метод несовершенен. Вполне возможно, что операции умножения и даже целые циклы были полностью пропущены C-компилятором, так как от их результата ничего не зависит.
Ожидается результат, когда первый запуск занимает много времени, а второй — меньше времени. В любом случае данные должны быть загружены в кэш, и это требует времени. После загрузки операции с этими данными занимают меньше времени.
Java может либо вообще не использовать кеш (маловероятно), либо предварительно загружать весь массив в кеш даже перед выполнением циклов. Это объясняет равные сроки исполнения.
У вас есть три размера кэша, это обычно
Все, что больше этого, не помещается в кеш, как будто вы просто прокручиваете память, как будто их там нет.
Я предлагаю вам написать тест, который эмпирически определяет размеры кэша ЦП, как хорошее упражнение, чтобы помочь вам понять это. Кстати, вам не нужно использовать *=
осуществлять кэш, как это упражнение ALU. Возможно, есть более простая операция, которую вы можете использовать;)
В случае вашего Java-кода, скорее всего, он еще не скомпилирован, поэтому вы видите скорость взаимодействия, а не доступ к памяти.
Я предлагаю вам повторно запустить тест на меньших объемах памяти в течение как минимум 2 секунд и взять среднее значение.