7

ここでは、ローカル、メンバー、揮発性メンバーのアクセス速度に関するテストを作成しました。

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) での結果です。

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

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

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

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

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

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

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

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

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

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

volatile メンバーへのアクセスが通常のメンバーの 100 倍遅いことに驚きました。揮発性メンバーに関するいくつかのハイライト機能があることを知っています。たとえば、変更がすべてのスレッドですぐに表示され、揮発性変数へのアクセスポイントが「メモリバリア」の役割を果たします。しかし、これらすべての副作用が 100 倍の速度低下の主な原因になるのでしょうか?

PS: Core II CPU マシンでもテストを行いました。約 9 時 50 分、約 5 倍遅いです。これはCPUアーチにも関係しているようです。5回はまだ大きいですよね?

4

4 に答える 4

8

揮発性メンバーはキャッシュされないため、メイン メモリから直接読み取られます。

于 2012-06-21T06:52:20.977 に答える
4

変数へのアクセスvolatileは、CPU がアクセスの前後に命令を並べ替えるのを防ぎます。これにより、通常、実行が遅くなります。

于 2012-06-21T05:42:21.093 に答える
4

にアクセスするとvolatile、一部の JIT 最適化が妨げられます。これは、実際には何もしないループがある場合に特に重要です。これは、JIT がそのようなループを最適化して取り除くことができるためです (揮発性フィールドがない場合)。

より現実的なテストでは、重要なvolatileコードの速度が 30% から 10 倍遅くなると予想される場合があります。ほとんどの実際のプログラムでは、CPU は 1 つのコアだけが揮発性フィールドを使用していることを「認識」し、メイン メモリを使用するのではなくそれをキャッシュするのに十分なほどスマートであるため、ほとんど違いはありません。

于 2012-06-21T07:08:38.923 に答える