SlideShare a Scribd company logo
了解CPU



        作者:周忱 | 淘宝综合业务
        微博:@MinZhou
        邮箱:zhouchen.zm@taobao.com
为什么Java程序员也需要了解CPU




                         关于我
 •   花名:周忱(chén)
 •   真名:周敏
 •   微博: @MinZhou
 •   Twitter: @minzhou
 •   2010年6月加入淘宝
 •   曾经淘宝Hadoop&Hive研发
     组Leader
 •   目前专注分布式实时计算
 •   Hive Contributor
 •   自由、开源软件热爱者




                               Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                         关于我
 •   花名:周忱(chén)
 •   真名:周敏
 •   微博: @MinZhou
 •   Twitter: @minzhou
 •   2010年6月加入淘宝
 •   曾经淘宝Hadoop&Hive研发
     组Leader
 •   目前专注分布式实时计算
 •   Hive Contributor
 •   自由、开源软件热爱者




                               Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                 什么是volatile?




                                Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                  Puzzle 1
  下面哪个程序跑得更快?

    private static long value;         private static volatile long value;

    public static void increment() {   public static void increment() {
      while (value < 100000000L) {       while (value < 100000000L) {
        value++;                           value++;
      }                                  }
    }                                  }



                                         如果换成AtomicLong呢?

                                                            Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                     Puzzle 2
   下面哪个程序跑得更快?

AtomicIntegerFieldUpdater state = …          AtomicIntegerFieldUpdater state= …

public void lock() {                         public void lock() {
  while(state.getAndSet(true)) {} ; //spin     while (true) {
}                                                while(state.get()) {}; //spin
                                                 if(!state.getAndSet(true))
                                                    return;
                                               }
                                             }

                                                      如果换成多线程呢?

                                                                  Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




           Intel 十年计划:Tick-Tock




                             Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                         CPU微架构变革
•   Hyper-threading
•   32KB L1d 与32KB L1i
•   256KB L2 Cache
•   4–12 MB L3 cache
•   QPI 代替FSB
•   PCI E和DMI整合入
    处理器, 北桥消失
•   支持 2/3通道DDR3




                                    Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                现代CPU微架构




                           Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




              Intel Nehalem 排布




                                 Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU



               Intel Sandy Bridge




                                    Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                      Puzzle 3
   下面哪个程序跑得更快?

 private static long[][] longs;              private static long[][] longs;

 for (int i = 0; i < DIMENSION_1; i++) {     for (int j = 0; j < DIMENSION_2; j++) {
   for (int j = 0; j < DIMENSION_2; j++) {     for (int i = 0; i < DIMENSION_1; i++){
       sum += longs[i][j];                         sum += longs[i][j];
    }                                           }
 }                                           }




                                                                   Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU



                            CPU Cache




   cat /sys/devices/system/cpu/cpu0/cache/index0/*
                                                     Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




           Cache Coherence & MESI协议
  •   M: 修改
  •   E : 独占
  •   S : 共享
  •   I : 失效




  发音: messy




                               Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                        Puzzle 4
   下面程序有什么问题?
 public final static class VolatileLong {    longs = new VolatileLong[NUM_THREADS];
   public volatile long value = 0L;          for (int i = 0; i < longs.length; i++) {
 }                                              longs[i] = new VolatileLong();
                                             }
 public class FS implements Runnable {       // 每个线程更新独立的变量
   public void run() {                       for (int i = 0; i < NUM_THREADS; i++) {
     long i = ITERATIONS + 1;                   threads[i] = new Thread(new FS(i)));
     while (0 != --i) {                      }
        longs[arrayIndex].value = i;        for (Thread t : threads) {
     }                                          t.start();
   }                                         }
 }                                          for (Thread t : threads) {
                                                t.join();
                                             }
                                                                   Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     False Sharing
                            public final static class VolatileLong {
                              public volatile long value = 0L;
                            }


                            =>

                            public final static class VolatileLong {
                              public volatile long value = 0L;
                              public long p1, p2, p3, p4, p5, p6;
                            }




                                                  Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     False Sharing
                            public final static class VolatileLong {
                              public volatile long value = 0L;
                            }


                            =>

                            public final static class VolatileLong {
                              public volatile long value = 0L;
                              public long p1, p2, p3, p4, p5, p6;
                            }




                                                  Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     False Sharing
                            public final static class VolatileLong {
                              public volatile long value = 0L;
                            }


                            =>

                            public final static class VolatileLong {
                              public volatile long value = 0L;
                              public long p1, p2, p3, p4, p5, p6;
                            }




                                                  Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




         Cache Consistency & 乱序执行
  •   CPU指令重排序




  •   编译重排序




                             Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                 Memory Ordering
  •   程序顺序(Program ordering): 读写和指令编制一致, 也称强顺序.
  •   处理器顺序(Processor ordering): 加快指令执行速度, 例如读可跨越它之前
      的buffered写

  •   Intel386及之前内存顺序模型: 程序顺序
  •   Pentium和Intel486内存顺序模型:大多数情况下遵循程序顺序
  •   P6及以后内存顺序模型:处理器顺序, 同时提供其它加强或弱化内存顺序
      模型的特殊指令




                                         Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     内存屏障
  •   Load Buffer
  •   Store Buffer
  •   CPU串行化指令
       – CPUID
       – SFENCE
       – LFENCE
       – MFENCE
  •   Lock系指令




                            Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                        Java内存模型
  •   Happens-Before       // Lock
  •   StoreStore          pthread_mutex_lock(&lock);
  •   LoadStore           sequence = i;
                          pthread_cond_signal(&condition);
  •   StoreLoad
                          pthread_mutex_unlock(&lock);
  •   LoadLoad
  •   Full Fence          // Soft Barrier
  •   锁和synchronized块     asm volatile(“” ::: “memory”);
  •   volatile 关键字        sequence = i;
  •   final 关键字
                          // Fence
                          asm volatile(“” ::: “memory”);
                          sequence = i;
                          asm volatile(“lock addl $0x0,(%rsp)”);

                                                      Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                     Java内存模型
                                           需要内存屏
  重排序                次操作                                                           次操作
                                             障
            Normal   Volatile   Volatile                                            Volatile
            Load     Load       Store                       Normal     Normal       Load         Volatile
 首操作                                       首操作
            Normal   Monitor    Monitor                     Load       Store        MonitorEnt   Store
                                                                                    er
            Store    Enter      Exit
 Normal                                    Normal Load                                           LoadStore
 Load
                                No
 Normal                                    Normal Store                                          StoreStore
 Store
 Volatile
 Load                                      Volatile Load
            No       No         No                          LoadLoad   LoadStore    LoadLoad     LoadStore
                                           MonitorEnter
 Monitor
 Enter
 Volatile
 store                                     Volatile Store
                     No         No                                                  StoreLoad    StoreStore
 Monitor                                   MonitorExit
 Exit

                                                                                Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                           Example
1. class X {                   $ java -XX:+UnlockDiagnosticVMOptions -XX:PrintAssemblyOptions=hsdis-print-bytes -
2.   int a, b;                 XX:CompileCommand=print,X.f X
3.   volatile int v, u;
4.   void f() {                …
5.     int i, j;
6.
7.     i = a; // load a
                               [Verified Entry Point]
8.     j = b; // load b         0xb3a1e28c: push %ebp ;...55
9.     i = v; // load v         0xb3a1e28d: sub $0x8,%esp ;...81ec0800 0000
10.            // LoadLoad      0xb3a1e293: mov 0x10(%ecx),%ebx ;...8b5910 ; i = v
11.    j = u; // load u         0xb3a1e296: mov 0x14(%ecx),%edi ;...8b7914 ; j = u
12.            // LoadStore     0xb3a1e299: mov %ebx,0x8(%ecx) ;...895908 ; a = i
13.    a = i; // store a        0xb3a1e29c: mov %edi,0xc(%ecx) ;...89790c      ;b=j
14.    b = j; // store b        0xb3a1e29f: mov %ebx,0x10(%ecx) ;...895910 ; v = i
15.            // StoreStore    0xb3a1e2a2: mov %edi,0x14(%ecx) ;...897914 ; u = j
16.    v = i; // store v        0xb3a1e2a5: lock addl $0x0,(%esp) ;...f0830424 ; memory barrier
17.            // StoreStore
                                0xb3a1e2aa: mov 0x14(%ecx),%ebp ;...8b6914 ; i = u
18.    u = j; // store u
19.            // StoreLoad
                                0xb3a1e2ad: mov %ebp,0x8(%ecx) ;...896908 ; a = i
20.    i = u; // load u         0xb3a1e2b0: add $0x8,%esp ;...83c408
21.            // LoadLoad      0xb3a1e2b3: pop %ebp ;...5d
22.            // LoadStore     0xb3a1e2b4: test %eax,0xb78ab000 ;...850500b0 8ab7
23.    j = b; // load b
24.    a = i; // store a       …
25. }
26.}
                               参考: jdk/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp
                                                                                       Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                        Puzzle 5


  为什么有volatile还需要AtomicXX及
  Unsafe.compareAndSwapXX?




                                   Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                            原子指令
  •   CompareAndSwap: LOCK XCHG
  •   LOCK XADD
  •   ABA问题




                                   Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                       让步锁

 public class BackoffLock {                   if (!state.getAndSet(true)) {
  private AtomicBoolean state = new                  return;
 AtomicBoolean(false);                             } else {
  private static final int MIN_DELAY = ...;          backoff.backoff();
  private static final int MAX_DELAY = ...;        }
                                                 }
  public void lock() {                         }
   Backoff backoff = new Backoff(MIN_DELAY,
 MAX_DELAY);                                      public void unlock() {
   while (true) {                                   state.set(false);
    while (state.get()) {};                       }

                                              }

                                                                  Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                                   队列锁
  •   BackOff锁的问题
       – Cache-coherence Traffic
       – 临界区利用率
       – 公平性问题
       – 饥饿
  •   基于数组的队列
  •   CLH队列
  •   MCS队列
  •   NUMA-Aware变种




                    https://blogs.oracle.com/dave/entry/flat_combining_numa_locks
                                                             Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     Puzzle 6


     为什么j.u.c或者jvm里面在加锁的时候, 喜欢用先
     CAS spin尝试N次, 如果失败则yield多次(可选), 如果
     最后还是失败则park, 同时把线程加到队列里?




                                Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                              工具
   •   top
   •   vmstat
   •   lscpu
   •   perf
   •   Valgrind tools suite
   •   OProfile
   •   SystemTap
   •   numactl
   •   Intel Vtune
   •   MAT


                                   Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                             推荐读物
   •   What every programmer should know about memory
   •   Intel® 64 and IA-32 Architectures Software Developer Manuals
   •   The Art of Multiprocessor Programming
   •   The JSR-133 Cookbook for Compiler Writers (Java Memory Model)
   •   本人博客: http://coderplay.javaeye.com




                                                       Taobao Java Team | zhouchen.zm
为什么Java程序员也需要了解CPU




                     Q&A




                           作者:周忱 | 淘宝综合业务
                           微博:@MinZhou
                           邮箱:zhouchen.zm@taobao.com



                                   Taobao Java Team | zhouchen.zm

More Related Content

PDF
Java trouble shooting
PDF
Java Concurrent Optimization: Concurrent Queue
PPT
JVM内容管理和垃圾回收
PDF
Java cpu
PDF
Btrace intro(撒迦)
PDF
JVM及其调优
PPTX
为啥别读HotSpot VM的源码(2012-03-03)
Java trouble shooting
Java Concurrent Optimization: Concurrent Queue
JVM内容管理和垃圾回收
Java cpu
Btrace intro(撒迦)
JVM及其调优
为啥别读HotSpot VM的源码(2012-03-03)

What's hot (20)

PPTX
Jvm基础调优实践(v1.0)
PDF
Java线上应用问题排查方法和工具(空望)
PPTX
Java Crash分析(2012-05-10)
PPTX
并发编程交流
PPTX
线上问题排查交流
PDF
合久必分,分久必合
PPT
系统性能分析和优化.ppt
PPTX
Sun jdk 1.6内存管理 -使用篇
PPTX
From Java Stream to Java DataFrame
PPTX
Java常见问题排查
PPTX
Java内存管理问题案例分享
PPTX
給初學者的Spark教學
PDF
Android开发基础
PPTX
Sun JDK 1.6内存管理 -调优篇
PPTX
高性能的Java代码编写及常见问题排查
KEY
D2_Node在淘宝的应用实践
PDF
Java GC Tuning
PPTX
UseNUMA做了什么?(2012-03-14)
PPT
Jvm内存管理基础
PPTX
Avm2虚拟机浅析与as3性能优化(陈士凯)
Jvm基础调优实践(v1.0)
Java线上应用问题排查方法和工具(空望)
Java Crash分析(2012-05-10)
并发编程交流
线上问题排查交流
合久必分,分久必合
系统性能分析和优化.ppt
Sun jdk 1.6内存管理 -使用篇
From Java Stream to Java DataFrame
Java常见问题排查
Java内存管理问题案例分享
給初學者的Spark教學
Android开发基础
Sun JDK 1.6内存管理 -调优篇
高性能的Java代码编写及常见问题排查
D2_Node在淘宝的应用实践
Java GC Tuning
UseNUMA做了什么?(2012-03-14)
Jvm内存管理基础
Avm2虚拟机浅析与as3性能优化(陈士凯)
Ad

Similar to Java程序员也需要了解CPU (20)

PDF
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
PPT
线程与并发
PDF
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
PPTX
DevOpsDays Taipei 2018 - Puppet 古早味、新感受:改造老牌企業進入自動化時代
PPT
千呼萬喚始出來的Java SE 7
PPT
高性能并发Web服务器实现核心内幕
PPT
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
PDF
D2_node在淘宝的应用实践_pdf版
PPTX
JavaScript 80+ Programming and Optimization Skills
KEY
Scala
PPT
Node.js在淘宝的应用实践
PDF
Python 于 webgame 的应用
PPTX
服务器端性能优化 提升Qps、rt
PPT
IKVM.NET 深入敵營的 Java
PDF
千呼萬喚始出來的 Java SE 7
PPT
Phpunit入门 r2
ODP
Java 網路程式
PDF
如何在 Java App 中導入 Scala
PDF
Jni攻略之十一――启动虚拟机调用Java类
PDF
Java Thread
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
线程与并发
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
DevOpsDays Taipei 2018 - Puppet 古早味、新感受:改造老牌企業進入自動化時代
千呼萬喚始出來的Java SE 7
高性能并发Web服务器实现核心内幕
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
D2_node在淘宝的应用实践_pdf版
JavaScript 80+ Programming and Optimization Skills
Scala
Node.js在淘宝的应用实践
Python 于 webgame 的应用
服务器端性能优化 提升Qps、rt
IKVM.NET 深入敵營的 Java
千呼萬喚始出來的 Java SE 7
Phpunit入门 r2
Java 網路程式
如何在 Java App 中導入 Scala
Jni攻略之十一――启动虚拟机调用Java类
Java Thread
Ad

More from Min Zhou (7)

PDF
Distributed Data Analytics at Taobao
PPTX
Big Data Analytics Infrastructure
PDF
准实时海量数据分析系统架构探究
PDF
Hive
PPTX
淘宝Hadoop数据分析实践
PPT
Anthill: A Distributed DBMS Based On MapReduce
PPT
Redpoll
Distributed Data Analytics at Taobao
Big Data Analytics Infrastructure
准实时海量数据分析系统架构探究
Hive
淘宝Hadoop数据分析实践
Anthill: A Distributed DBMS Based On MapReduce
Redpoll

Java程序员也需要了解CPU

  • 1. 了解CPU 作者:周忱 | 淘宝综合业务 微博:@MinZhou 邮箱:zhouchen.zm@taobao.com
  • 2. 为什么Java程序员也需要了解CPU 关于我 • 花名:周忱(chén) • 真名:周敏 • 微博: @MinZhou • Twitter: @minzhou • 2010年6月加入淘宝 • 曾经淘宝Hadoop&Hive研发 组Leader • 目前专注分布式实时计算 • Hive Contributor • 自由、开源软件热爱者 Taobao Java Team | zhouchen.zm
  • 3. 为什么Java程序员也需要了解CPU 关于我 • 花名:周忱(chén) • 真名:周敏 • 微博: @MinZhou • Twitter: @minzhou • 2010年6月加入淘宝 • 曾经淘宝Hadoop&Hive研发 组Leader • 目前专注分布式实时计算 • Hive Contributor • 自由、开源软件热爱者 Taobao Java Team | zhouchen.zm
  • 4. 为什么Java程序员也需要了解CPU 什么是volatile? Taobao Java Team | zhouchen.zm
  • 5. 为什么Java程序员也需要了解CPU Puzzle 1 下面哪个程序跑得更快? private static long value; private static volatile long value; public static void increment() { public static void increment() { while (value < 100000000L) { while (value < 100000000L) { value++; value++; } } } } 如果换成AtomicLong呢? Taobao Java Team | zhouchen.zm
  • 6. 为什么Java程序员也需要了解CPU Puzzle 2 下面哪个程序跑得更快? AtomicIntegerFieldUpdater state = … AtomicIntegerFieldUpdater state= … public void lock() { public void lock() { while(state.getAndSet(true)) {} ; //spin while (true) { } while(state.get()) {}; //spin if(!state.getAndSet(true)) return; } } 如果换成多线程呢? Taobao Java Team | zhouchen.zm
  • 7. 为什么Java程序员也需要了解CPU Intel 十年计划:Tick-Tock Taobao Java Team | zhouchen.zm
  • 8. 为什么Java程序员也需要了解CPU CPU微架构变革 • Hyper-threading • 32KB L1d 与32KB L1i • 256KB L2 Cache • 4–12 MB L3 cache • QPI 代替FSB • PCI E和DMI整合入 处理器, 北桥消失 • 支持 2/3通道DDR3 Taobao Java Team | zhouchen.zm
  • 9. 为什么Java程序员也需要了解CPU 现代CPU微架构 Taobao Java Team | zhouchen.zm
  • 10. 为什么Java程序员也需要了解CPU Intel Nehalem 排布 Taobao Java Team | zhouchen.zm
  • 11. 为什么Java程序员也需要了解CPU Intel Sandy Bridge Taobao Java Team | zhouchen.zm
  • 12. 为什么Java程序员也需要了解CPU Puzzle 3 下面哪个程序跑得更快? private static long[][] longs; private static long[][] longs; for (int i = 0; i < DIMENSION_1; i++) { for (int j = 0; j < DIMENSION_2; j++) { for (int j = 0; j < DIMENSION_2; j++) { for (int i = 0; i < DIMENSION_1; i++){ sum += longs[i][j]; sum += longs[i][j]; } } } } Taobao Java Team | zhouchen.zm
  • 13. 为什么Java程序员也需要了解CPU CPU Cache cat /sys/devices/system/cpu/cpu0/cache/index0/* Taobao Java Team | zhouchen.zm
  • 14. 为什么Java程序员也需要了解CPU Cache Coherence & MESI协议 • M: 修改 • E : 独占 • S : 共享 • I : 失效 发音: messy Taobao Java Team | zhouchen.zm
  • 15. 为什么Java程序员也需要了解CPU Puzzle 4 下面程序有什么问题? public final static class VolatileLong { longs = new VolatileLong[NUM_THREADS]; public volatile long value = 0L; for (int i = 0; i < longs.length; i++) { } longs[i] = new VolatileLong(); } public class FS implements Runnable { // 每个线程更新独立的变量 public void run() { for (int i = 0; i < NUM_THREADS; i++) { long i = ITERATIONS + 1; threads[i] = new Thread(new FS(i))); while (0 != --i) { } longs[arrayIndex].value = i; for (Thread t : threads) { } t.start(); } } } for (Thread t : threads) { t.join(); } Taobao Java Team | zhouchen.zm
  • 16. 为什么Java程序员也需要了解CPU False Sharing public final static class VolatileLong { public volatile long value = 0L; } => public final static class VolatileLong { public volatile long value = 0L; public long p1, p2, p3, p4, p5, p6; } Taobao Java Team | zhouchen.zm
  • 17. 为什么Java程序员也需要了解CPU False Sharing public final static class VolatileLong { public volatile long value = 0L; } => public final static class VolatileLong { public volatile long value = 0L; public long p1, p2, p3, p4, p5, p6; } Taobao Java Team | zhouchen.zm
  • 18. 为什么Java程序员也需要了解CPU False Sharing public final static class VolatileLong { public volatile long value = 0L; } => public final static class VolatileLong { public volatile long value = 0L; public long p1, p2, p3, p4, p5, p6; } Taobao Java Team | zhouchen.zm
  • 19. 为什么Java程序员也需要了解CPU Cache Consistency & 乱序执行 • CPU指令重排序 • 编译重排序 Taobao Java Team | zhouchen.zm
  • 20. 为什么Java程序员也需要了解CPU Memory Ordering • 程序顺序(Program ordering): 读写和指令编制一致, 也称强顺序. • 处理器顺序(Processor ordering): 加快指令执行速度, 例如读可跨越它之前 的buffered写 • Intel386及之前内存顺序模型: 程序顺序 • Pentium和Intel486内存顺序模型:大多数情况下遵循程序顺序 • P6及以后内存顺序模型:处理器顺序, 同时提供其它加强或弱化内存顺序 模型的特殊指令 Taobao Java Team | zhouchen.zm
  • 21. 为什么Java程序员也需要了解CPU 内存屏障 • Load Buffer • Store Buffer • CPU串行化指令 – CPUID – SFENCE – LFENCE – MFENCE • Lock系指令 Taobao Java Team | zhouchen.zm
  • 22. 为什么Java程序员也需要了解CPU Java内存模型 • Happens-Before // Lock • StoreStore pthread_mutex_lock(&lock); • LoadStore sequence = i; pthread_cond_signal(&condition); • StoreLoad pthread_mutex_unlock(&lock); • LoadLoad • Full Fence // Soft Barrier • 锁和synchronized块 asm volatile(“” ::: “memory”); • volatile 关键字 sequence = i; • final 关键字 // Fence asm volatile(“” ::: “memory”); sequence = i; asm volatile(“lock addl $0x0,(%rsp)”); Taobao Java Team | zhouchen.zm
  • 23. 为什么Java程序员也需要了解CPU Java内存模型 需要内存屏 重排序 次操作 次操作 障 Normal Volatile Volatile Volatile Load Load Store Normal Normal Load Volatile 首操作 首操作 Normal Monitor Monitor Load Store MonitorEnt Store er Store Enter Exit Normal Normal Load LoadStore Load No Normal Normal Store StoreStore Store Volatile Load Volatile Load No No No LoadLoad LoadStore LoadLoad LoadStore MonitorEnter Monitor Enter Volatile store Volatile Store No No StoreLoad StoreStore Monitor MonitorExit Exit Taobao Java Team | zhouchen.zm
  • 24. 为什么Java程序员也需要了解CPU Example 1. class X { $ java -XX:+UnlockDiagnosticVMOptions -XX:PrintAssemblyOptions=hsdis-print-bytes - 2. int a, b; XX:CompileCommand=print,X.f X 3. volatile int v, u; 4. void f() { … 5. int i, j; 6. 7. i = a; // load a [Verified Entry Point] 8. j = b; // load b 0xb3a1e28c: push %ebp ;...55 9. i = v; // load v 0xb3a1e28d: sub $0x8,%esp ;...81ec0800 0000 10. // LoadLoad 0xb3a1e293: mov 0x10(%ecx),%ebx ;...8b5910 ; i = v 11. j = u; // load u 0xb3a1e296: mov 0x14(%ecx),%edi ;...8b7914 ; j = u 12. // LoadStore 0xb3a1e299: mov %ebx,0x8(%ecx) ;...895908 ; a = i 13. a = i; // store a 0xb3a1e29c: mov %edi,0xc(%ecx) ;...89790c ;b=j 14. b = j; // store b 0xb3a1e29f: mov %ebx,0x10(%ecx) ;...895910 ; v = i 15. // StoreStore 0xb3a1e2a2: mov %edi,0x14(%ecx) ;...897914 ; u = j 16. v = i; // store v 0xb3a1e2a5: lock addl $0x0,(%esp) ;...f0830424 ; memory barrier 17. // StoreStore 0xb3a1e2aa: mov 0x14(%ecx),%ebp ;...8b6914 ; i = u 18. u = j; // store u 19. // StoreLoad 0xb3a1e2ad: mov %ebp,0x8(%ecx) ;...896908 ; a = i 20. i = u; // load u 0xb3a1e2b0: add $0x8,%esp ;...83c408 21. // LoadLoad 0xb3a1e2b3: pop %ebp ;...5d 22. // LoadStore 0xb3a1e2b4: test %eax,0xb78ab000 ;...850500b0 8ab7 23. j = b; // load b 24. a = i; // store a … 25. } 26.} 参考: jdk/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Taobao Java Team | zhouchen.zm
  • 25. 为什么Java程序员也需要了解CPU Puzzle 5 为什么有volatile还需要AtomicXX及 Unsafe.compareAndSwapXX? Taobao Java Team | zhouchen.zm
  • 26. 为什么Java程序员也需要了解CPU 原子指令 • CompareAndSwap: LOCK XCHG • LOCK XADD • ABA问题 Taobao Java Team | zhouchen.zm
  • 27. 为什么Java程序员也需要了解CPU 让步锁 public class BackoffLock { if (!state.getAndSet(true)) { private AtomicBoolean state = new return; AtomicBoolean(false); } else { private static final int MIN_DELAY = ...; backoff.backoff(); private static final int MAX_DELAY = ...; } } public void lock() { } Backoff backoff = new Backoff(MIN_DELAY, MAX_DELAY); public void unlock() { while (true) { state.set(false); while (state.get()) {}; } } Taobao Java Team | zhouchen.zm
  • 28. 为什么Java程序员也需要了解CPU 队列锁 • BackOff锁的问题 – Cache-coherence Traffic – 临界区利用率 – 公平性问题 – 饥饿 • 基于数组的队列 • CLH队列 • MCS队列 • NUMA-Aware变种 https://blogs.oracle.com/dave/entry/flat_combining_numa_locks Taobao Java Team | zhouchen.zm
  • 29. 为什么Java程序员也需要了解CPU Puzzle 6 为什么j.u.c或者jvm里面在加锁的时候, 喜欢用先 CAS spin尝试N次, 如果失败则yield多次(可选), 如果 最后还是失败则park, 同时把线程加到队列里? Taobao Java Team | zhouchen.zm
  • 30. 为什么Java程序员也需要了解CPU 工具 • top • vmstat • lscpu • perf • Valgrind tools suite • OProfile • SystemTap • numactl • Intel Vtune • MAT Taobao Java Team | zhouchen.zm
  • 31. 为什么Java程序员也需要了解CPU 推荐读物 • What every programmer should know about memory • Intel® 64 and IA-32 Architectures Software Developer Manuals • The Art of Multiprocessor Programming • The JSR-133 Cookbook for Compiler Writers (Java Memory Model) • 本人博客: http://coderplay.javaeye.com Taobao Java Team | zhouchen.zm
  • 32. 为什么Java程序员也需要了解CPU Q&A 作者:周忱 | 淘宝综合业务 微博:@MinZhou 邮箱:zhouchen.zm@taobao.com Taobao Java Team | zhouchen.zm