这是Linux/GUN下的C程序:
#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
几乎是一样的
与 CPU 缓存。为什么他们有这么大的差异? Cpu Cache在C编程中无效?
最佳答案
我希望您意识到这些测试中时间单位的差异是 10^3。 C 代码比 Java 代码快一个数量级。
在 C 代码中应该有 a[i]
而不是 a[Max]
。
至于缓存:由于您在 C 代码中只访问一个内存位置(这会触发未定义的行为),因此您的 C 测试完全无效。
即使它是正确的,你的方法也有缺陷。 C 编译器很可能完全跳过了乘法运算甚至整个循环,因为它们的结果完全无关。
第一次运行时间较长而第二次运行时间较短的结果是预期的。无论如何都必须将数据加载到缓存中,这需要时间。加载后,对该数据的操作将花费更少的时间。
Java 可能根本不使用缓存(不太可能),或者甚至在执行循环之前就将整个数组预加载到缓存中。这可以解释相等的执行时间。
关于java - CPU缓存在C编程中无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19873842/