关于 CPU 的缓存的证明和应用

证明: 首先,我们都知道现在的 CPU 多核技术,同时会有三级缓存(L1,L2,L3 ),如图: 缓存基本上来说就是把后面的数据加载到离自己近的地方,对于 CPU 来说,是一个字节一个字节的加载数据的吗?其实不是的,一般来说都是要一块一块的加载的,对于这样的一块一块的数据单位,我们叫做“Cache Line”,中文翻译:缓存行,一般来说,一个主流的 CPU 的 Cache Line 是 64 Bytes,也就是 8 个 64 位的整型,这就是 CPU 从内存中捞数据上来的最小数据单位。那么这个如何证明呢? package cn.bridgeli.demo; import java.util.concurrent.CountDownLatch; /** * @author BridgeLi * @date 2021/11/29 20:41 */ public class CacheLineTest { private static long loop = 1_0000_0000L; private static class T { // private volatile long x1, x2, x3, x4, x5, x6, x7; private volatile long x = 0L; // private volatile long x8, x9, x10, x11, x12, x13, x14; } private static T[] arr = new T[2]; static { arr[0] = new T(); arr[1] = new T(); } public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(2); Thread t1 = new Thread(() -> { for (long i = 0; i < loop; i++) { arr[0].x = i; } countDownLatch.countDown(); }, "t1"); Thread t2 = new Thread(() -> { for (long i = 0; i < loop; i++) { arr[1].x = i; } countDownLatch.countDown(); }, "t2"); long currentTimeMillis = System.currentTimeMillis(); t1.start(); t2.start(); countDownLatch.await(); System.out.println(System.currentTimeMillis() &#8211; currentTimeMillis); } } 我们定义了一个长度为 2 的数组,数组中的元素是 T 类型,T 有一个属性 x,我们同时启动两个线程分别给第一个元素和第二个元素中的 x 复制从 0 到一亿减 1,这个时候我们测试他耗时多少,不同的电脑配置肯定是不同的,我的电脑大概是四千多毫秒,然后我们把 T 对象中属性 x 前后各被注释调的一行打开再跑一次看看,变成了大概 700 毫秒,相差整整 6 倍!这是为何? ...

November 29, 2021 · 2 min · 279 words · Bridge Li