Thread Affinity是什么意思?

时间:2013-10-25 10:27:30

标签: java multithreading concurrency

我听说过Thread Affinity和Thread Affinity Executor。但至少在java中我无法找到适当的参考。有人可以向我解释一下这是什么意思吗?

4 个答案:

答案 0 :(得分:49)

有两个问题。首先,线程最好与某个CPU(核心)具有亲缘关系,以充分利用其CPU本地缓存。这必须由操作系统处理。线程的这个CPU affinity通常也称为“线程关联”。在Java的情况下,没有标准API来控制它。但是有第三方图书馆,正如其他答案所提到的那样。

其次,在Java中,观察到在典型的程序中对象是线程仿射的,即通常在大多数时间仅由一个线程使用。因此,JVM优化器的任务是确保将一个线程所关联的对象在内存中彼此靠近放置以适合一个CPU的缓存,但是将对象关联到不同的线程并不太靠近彼此以避免它们共享一个高速缓存行,否则两个CPU /核心必须经常同步它们。

理想情况是,CPU可以独立处理某些对象,而不是处理位于不相关内存区域中的其他对象的另一个CPU。

考虑到Java对象的线程亲和性的优化实例是

  • Thread-Local Allocation Buffers (TLABs)

    使用TLAB,每个对象在专用于创建它的线程的内存区域中开始其生命周期。根据世代垃圾收集器背后的主要假设(“所有对象的大部分将会死亡”),大多数对象将在其整个生命周期中都花费在这样的线程本地缓冲区中。

  • Biased Locking

    使用偏向锁定,JVM将执行锁定操作,乐观假设对象将仅由同一个线程锁定,只有在此假设不成立时才切换到更昂贵的锁定实现。

  • @Contended

    为了解决另一端,已知多个线程访问的字段,HotSpot / OpenJDK有一个注释,当前不是公共API的一部分,用于标记它们,以指示JVM将这些数据从其他可能未共享的数据。

答案 1 :(得分:9)

让我尝试解释一下。随着多核处理器的兴起,线程与线程之间的消息传递;线程池,调度变得更加昂贵。为什么这比以前变得更重,因为我们需要理解“机械同情”的概念。有关详细信息,您可以查看blog。但粗略地说,当线程分布在处理器的不同核心时,当它们尝试交换消息时;缓存未命中概率很高。现在讨论您的具体问题,线程关联能够将特定线程分配给特定处理器/核心。这是java的library之一,可用于它。

答案 2 :(得分:5)

Java Thread Affinity version 1.4 library尝试通过允许您为关键线程保留逻辑线程,并为最具性能敏感性的线程保留整个核心,尝试充分利用这两个方面。不太重要的线程仍将运行超线程的优势。例如以下代码段

AffinityLock al = AffinityLock.acquireLock();
    try {
        // find a cpu on a different socket, otherwise a different core.
        AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET, DIFFERENT_CORE);
        new Thread(new SleepRunnable(readerLock, false), "reader").start();

        // find a cpu on the same core, or the same socket, or any free cpu.
        AffinityLock writerLock = readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY);
        new Thread(new SleepRunnable(writerLock, false), "writer").start();

        Thread.sleep(200);
    } finally {
        al.release();
    }

    // allocate a whole core to the engine so it doesn't have to compete for resources.
    al = AffinityLock.acquireCore(false);
    new Thread(new SleepRunnable(al, true), "engine").start();

    Thread.sleep(200);
    System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());

答案 3 :(得分:3)

线程关联(或进程关联)描述了允许线程/进程运行的处理器核心。通常,此设置等于系统中的(逻辑)CPU,并且几乎没有理由更改此设置,因为操作系统具有在可用处理器之间安排任务的最佳可能性。

请参阅ie http://msdn.microsoft.com/en-us/library/windows/desktop/ms683213(v=vs.85).aspx了解其在Windows中的工作原理。我不知道java是否提供了一个API来设置它们。