2013-03-11 25 views
8

我想实现一个像ThreadLocal一样工作的CoreLocal映射,只有它返回一个特定于当前线程运行的核心的值。如何确定运行Java线程的内核?

原因是我想编写代码从队列中取出作业,但我想优先考虑将其关联数据与拾取从队列中的工作。因此,我不希望整个程序有一个作业队列,而是希望每个核心都有一个队列,只有当队列为空时,工作线程才会查看其他核心的队列。

+3

https://github.com/peter-lawrey/Java-Thread-Affinity – bmargulies 2013-03-11 22:52:05

+2

Q ==队列? :\ – 2013-03-11 22:52:12

+3

听起来就像你在那里的纳秒时间真的很低。 – djechlin 2013-03-11 22:57:40

回答

0

也许你可以检查/proc/[pid]/status

这些字段可能会有所帮助:

Cpus_allowed:CPU的面膜在此过程中可能会遇到

Cpus_allowed_list:同以前的,但在“名单格式“

1

有一个相关linux question没有满意的答案(解析top输出不计数,接受的答案不再有效)。我认为

/proc/<pid>/task/<tid>/sched 

可能给该信息在一条线上像

current_node=0, numa_group_id=0 

但上运行4.4.0-92-通用内核我i5-2400,该行始终是所有线程的相同。我想,“节点”意味着整个CPU(套接字),我只有一个。

我找不到这方面的文档,或在this document中错过了。


然而,恐怕这获得这些信息可能难以相信帮助你:

  • 从proc文件系统读数可以在你工作的规模过于昂贵。
  • ThreadLocal不同,您的CoreLocal不是线程安全的:将线程移植到另一个核心可能会破坏像someCoreLocalField++这样的微不足道的非原子操作。暂停它也会这样做。所以你需要一些原子或线程本地化来实现它,这可能会让它变得太慢而不能满足你的需求。
0

我不认为有任何调用来获取目前在JDK暴露了当前的CPU,但它肯定已经previously discussedproposed as a JDK enhancement

我认为,直到类似的东西得到实施最好的办法是使用类似JNA(简单)或JNI(快)包本机的系统调用像getcpu在Linux或GetCurrentProcessorNumber在Windows上。

至少在Linux上,getcpu在VDSO中实现,没有内核转换,所以它应该只需要几纳秒,再加上几个纳秒的JNI调用。 JNA较慢。

如果你的确实是需要速度,你可以随时添加函数作为定制JVM的内在函数(因为OpenJDK是开源的)。这将削减几个纳秒。

请记住,这些信息一旦得到就可能过时,所以您绝不应该依赖它来获得性能,而只需要正确性。由于您已获得“错误”值的支持,因此另一种可能的方法是将缓存的CPU ID值存储在ThreadLocal中,并且只能定期更新。这使得缓慢的方法,例如解析/proc文件系统可行,因为你很少做它们。为了获得最大速度,您可以定期从定时器线程中使线程本地无效,而不是检查每个调用的失效条件。


两者的讨论和增强请求是高度推荐的读数。

相关问题