为什么访问volatile变量比成员慢约100?

Dee*_*Two 7 java performance volatile

在这里,我写了一个关于local,member,volatile成员的访问速度的测试:

public class VolatileTest {

public int member = -100;

public volatile int volatileMember = -100;

public static void main(String[] args) {
    int testloop = 10;
    for (int i = 1; i <= testloop; i++) {
        System.out.println("Round:" + i);
        VolatileTest vt = new VolatileTest();
        vt.runTest();
        System.out.println();
    }
}

public void runTest() {
    int local = -100;

    int loop = 1;
    int loop2 = Integer.MAX_VALUE;
    long startTime;

    startTime = System.currentTimeMillis();
    for (int i = 0; i < loop; i++) {
        for (int j = 0; j < loop2; j++) {
        }
        for (int j = 0; j < loop2; j++) {
        }
    }
    System.out.println("Empty:" + (System.currentTimeMillis() - startTime));

    startTime = System.currentTimeMillis();
    for (int i = 0; i < loop; i++) {
        for (int j = 0; j < loop2; j++) {
            local++;
        }
        for (int j = 0; j < loop2; j++) {
            local--;
        }
    }
    System.out.println("Local:" + (System.currentTimeMillis() - startTime));

    startTime = System.currentTimeMillis();
    for (int i = 0; i < loop; i++) {
        for (int j = 0; j < loop2; j++) {
            member++;
        }
        for (int j = 0; j < loop2; j++) {
            member--;
        }
    }
    System.out.println("Member:" + (System.currentTimeMillis() - startTime));

    startTime = System.currentTimeMillis();
    for (int i = 0; i < loop; i++) {
        for (int j = 0; j < loop2; j++) {
            volatileMember++;
        }
        for (int j = 0; j < loop2; j++) {
            volatileMember--;
        }
    }
    System.out.println("VMember:" + (System.currentTimeMillis() - startTime));

}
}
Run Code Online (Sandbox Code Playgroud)

这是我的X220(I5 CPU)的结果:

回合:1空:5本地:10成员:312 VMember:33378

回合:2空:31本地:0会员:294 VMember:33180

回合:3空:0本地:0成员:306 VMember:33085

回合:4空:0本地:0成员:300 VMember:33066

回合:5空:0本地:0成员:303 VMember:33078

回合:6空:0本地:0成员:299 VMember:33398

回合:7空:0本地:0成员:305 VMember:33139

回合:8空:0本地:0成员:307 VMember:33490

回合:9空:0本地:0成员:350 VMember:35291

回合:10空:0本地:0成员:332 VMember:33838

让我感到惊讶的是,对volatile组件的访问速度比普通成员慢100倍.我知道有一些关于volatile成员的突出特性,比如对它的修改将立即对所有线程可见,对volatile变量的访问点起到"内存屏障"的作用.但所有这些副作用能否成为100倍慢的主要原因?

PS:我还在Core II CPU机器上进行了测试.大概是9:50,大约慢5倍.看起来这也与CPU拱形有关.5次还是大的吧?

me_*_*jay 7

volatile缓存成员永远不会被缓存,因此可以直接从主内存中读取它们.


Pet*_*rey 4

阻止某些 JIT 优化的访问volatile。如果您有一个实际上不执行任何操作的循环,这一点尤其重要,因为 JIT 可以优化此类循环(除非您有一个易失性字段),如果您“长时间”运行循环,则差异应该会增加更多。

在更实际的测试中,您可能预计volatile关键代码的速度会慢 30% 到 10 倍。在大多数实际程序中,这几乎没有什么区别,因为 CPU 足够聪明,可以“意识到”只有一个内核正在使用易失性字段并对其进行缓存,而不是使用主内存。