为什么访问volatile变量比成员慢约100? [英] Why access volatile variable is about 100 slower than member?

查看:188
本文介绍了为什么访问volatile变量比成员慢约100?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,我写了一个关于本地,成员,易变成员访问速度的测试:

Here I wrote a test about access speed of local, member, volatile member:

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));

}
}

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

And here is a result on my X220 (I5 CPU):

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

Round:1 Empty:5 Local:10 Member:312 VMember:33378

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

Round:2 Empty:31 Local:0 Member:294 VMember:33180

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

Round:3 Empty:0 Local:0 Member:306 VMember:33085

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

Round:4 Empty:0 Local:0 Member:300 VMember:33066

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

Round:5 Empty:0 Local:0 Member:303 VMember:33078

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

Round:6 Empty:0 Local:0 Member:299 VMember:33398

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

Round:7 Empty:0 Local:0 Member:305 VMember:33139

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

Round:8 Empty:0 Local:0 Member:307 VMember:33490

回合:9
空:0
当地:0
会员:350
VMember:35291

Round:9 Empty:0 Local:0 Member:350 VMember:35291

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

Round:10 Empty:0 Local:0 Member:332 VMember:33838

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

It surprised me that access to volatile member is 100 times slower than normal member. I know there is some highlight feature about volatile member, such as a modification to it will be visible for all thread immediately, access point to volatile variable plays a role of "memory barrier". But can all these side effect be the main cause of 100 times slow?

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

PS: I also did a test on a Core II CPU machine. It is about 9:50, about 5 times slow. seems like this is also related to CPU arch. 5 times is still big, right?

推荐答案

访问 volatile 可以防止一些JIT优化。如果你有一个没有真正做任何事情的循环,尤其重要,因为JIT可以优化这些循环(除非你有一个volatile字段)如果你运行循环long,那么descrepancy会增加更多。

Acess to volatile prevents some JIT optimisaton. This is especially important if you have a loop which doesn't really do anything as the JIT can optimise such loops away (unless you have a volatile field) If you run the loops "long" the descrepancy should increase more.

在更实际的测试中,您可能希望 volatile 对于cirtical代码要慢30%到10倍。在大多数真正的程序中它几乎没有什么区别,因为CPU足够聪明,可以意识到只有一个核心使用volatile字段并缓存它而不是使用主存储器。

In more realistic test, you might expect volatile to take between 30% and 10x slower for cirtical code. In most real programs it makes very little difference because the CPU is smart enough to "realise" that only one core is using the volatile field and cache it rather than using main memory.

这篇关于为什么访问volatile变量比成员慢约100?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆