...c3
13 0x03f83456: nopw 0x0(%eax,%eax,1) ;...66660f1f 840000
14 0x03f83460: mov -0x505a72f0(%ebp),%ebx ;...8b9d108d a5af
15 0x03f83466: test %edi,0xb78ec000 ;...853d00c0 8eb7
第三行和第十四行存在volatile读操作,而且都没有伴随内存屏障。也就是说 ,x86和SPARC上的volatile读操作的性能下降对于代码的优 化影响很小——指令 本身和常规读操作一样。
单向内存屏障本质上比双向屏障性能要好一些。JVM在确保单向屏障即可的情 况下会避免使用双向屏障。本文的第一个例子展示了这点。Itanium平台上的 连 续两次读操作被插入单向内存屏障。如果读操作插入显式双向内存屏障,程序仍 然正确,但是延迟比较长。
动态编译
静态编译器在构建阶段决定的一切事情,在动态编译器那里都可以在运行时决 定,甚至更多。更多信息意味着存在更多机会可以优化。例如,让我们看看 JVM 在单 处理器运行时如何对待内存屏障。以下指令流来自于通过Dekker算法实现两 次连续volatile写操作的运行时编译。程序运行于 x86硬件上的单处理器模式中 的VMWare工作站镜像。
1 0x017b474c: push %ebp ;...55
2 0x017b474d: sub $0x8,%esp ;...81ec0800 0000
3 0x017b4753: mov $0x14c,%edi ;...bf4c0100 00
4 0x017b4758: movb $0x1,-0x507572f0(%edi) ;...c687108d 8aaf01
5 0x017b475f: mov $0x148,%ebp ;...bd480100 00
6 0x017b4764: mov $0x14d,%edx ;...ba4d0100 00
7 0x017b4769: movsbl -0x507572f0(%edx),%ebx ;...0fbe9a10 8d8aaf
8 0x017b4770: test %ebx,%ebx ;...85db
9 0x017b4772: jne 0x017b4790 ;...751c
10 0x017b4774: movl $0x1,-0x507572f0(%ebp) ;...c785108d 8aaf01
11 0x017b477e: movb $0x0,-0x507572f0(%edi) ;...c687108d 8aaf00
12 0x017b4785: add $0x8,%esp ;...83c408
13 0x017b4788: pop %ebp ;...5d
内存屏障与JVM并发(7)
时间:2011-09-04 infoq 崔康译
在单处理器系统上,JVM为所有内存屏障插入了一个no op指令,因为内存操作 已经序列化了。每一个写操作(第10、11行)后面都跟着一个屏障。JVM针对原子 条件式做了类似的优化。下面的指令流来自于同一个VMWare镜像的 AtomicInteger.incrementAndGet动态编译结果。
1 0x036880f7: push %ebp ;...55
2 0x036880f8: mov %esp,%ebp ;...8bec
3 0x036880fa: sub $0x38,%esp ;...83ec38
4 0x036880fd: jmp 0x0368810a ;...e9080000 00
5 0x03688102: xchg %ax,%ax ;...6690
6 0x03688104: test %eax,0xb78b8100 ;...85050081 8bb7
7 0x0368810a: mov 0x8(%ecx),%eax ;...8b4108
8 0x0368810d: mov %eax,%esi ;...8bf0
9 0x0368810f: inc %esi ;...46
10 0x03688110: mov $0x9a3f03d0,%edi ;...bfd0033f 9a
11 0x03688115: mov 0x160(%edi),%edi ;...8bbf6001 0000
12 0x0368811b: mov %ecx,%edi ;...8bf9
13 0x0368811d: add $0x8,%edi ;...83c708
14 0x03688120: cmpxchg %esi,(%edi) ;...0fb137
15 0x03688123: mov $0x1,%eax ;...b8010000 00
16 0x03688128: je 0x03688133 ;...0f840500 0000
17 0x0368812e: mov $0x0,%eax
|