系统性能调优必知必会学习

1. cpu

多级缓存,32k -> 256k -> 20m

cat /sys/devices/system/cpu/cpu0/cache/index0/size
...
cat /sys/devices/system/cpu/cpu0/cache/index3/size
CPU Cache Line定义了缓存一次载入数据的大小
cat /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size 64
yum install perf

课程例子,按照内存顺序的访问利用缓存行可以带来性能的大幅提升

public class Test {
    public static void main(String args[]) {
        int TESTN = 4096;
        boolean slowMode = false;
        for (String arg : args) {
            if ("-f".equals(arg)) {
                slowMode = false;
                break;
            } else if ("-s".equals(arg)) {
                slowMode = true;
                break;
            }
        }

        char[][] arr = new char[TESTN][TESTN];
        Date start = new Date();
        if (!slowMode) {
            for (int i = 0; i < TESTN; i++) {
                for (int j = 0; j < TESTN; j++) {
                    //arr[i][j]是连续访问的
                    arr[i][j] = 0;
                }
            }
        } else {
            for (int i = 0; i < TESTN; i++) {
                for (int j = 0; j < TESTN; j++) {
                    //arr[j][i]是不连续访问的
                    arr[j][i] = 0;
                }
            }
        }
        System.out.println(new Date().getTime() - start.getTime());
    }
}

64 位操作系统的地址占用 8 个字节(32 位操作系统是 4 个字节),因此,每批 Cache Line 最多也就能载入不到 8 个二维数组元素,所以性能差距大约接近 8 倍

先排序的遍历时间只有后排序的三分之一,循环中有大量的 if 条件分支,而 CPU含有分支预测器,提前把这些指令放在缓存中,CPU 执行时就会很快。当数组中的元素完全随机时,分支预测器无法有效工作,而当 array 数组有序时,分支预测器会动态地根据历史命中数据对未来进行预测,命中率就会非常高

多线程并行访问不同的变量,这些变量在内存布局是相邻的(比如类中的多个变量),此时 CPU 缓存就会失效,java针对伪共享也做了填充等解决方案

原文地址:https://www.cnblogs.com/it-worker365/p/13175197.html