如何确定运行Java线程的核心?

时间:2013-03-11 22:49:22

标签: java multithreading performance core

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

这样做的原因是我想编写将从队列中获取作业的代码,但我想优先考虑那些将其关联数据放在与挑选作业的线程相同的L1缓存中的作业从队列中。因此,我想为整个程序创建一个队列,而不是每个核心都有一个队列,只有当队列为空时,工作线程才会查看其他核心的队列。

3 个答案:

答案 0 :(得分: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++这样的非原子操作。暂停它也会这样做。所以你需要一些原子或线程本地来使它工作,这也可能使它太慢你想要的东西。

答案 1 :(得分:1)

我认为没有任何调用来获取当前在JDK中公开的当前CPU,尽管它肯定是previously discussed 1 proposed as a JDK enhancement

我认为在实现类似内容之前,最好的办法是使用JNA(最简单)或JNI(快速)之类的东西来封装Linux上的getcpu本机系统调用或Windows上的GetCurrentProcessorNumber

至少在Linux上,getcpu是在没有内核转换的情况下在VDSO中实现的,因此它只需要几纳秒,再加上几纳秒的JNI调用。 JNA比较慢。

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

请记住,这些信息可能会在您获得后立即过期,因此您不应该依赖它来提高性能,只能依赖它。由于您已经获得了“错误”值的支持,另一种可能的方法是将CPU ID的缓存值存储在ThreadLocal中,并且只定期更新它。这使得解析/proc文件系统的速度变慢,因为您很少这样做。为了获得最大速度,您可以定期从定时器线程中使线程本地无效,而不是在每次调用时检查失效条件。

1 强烈建议阅读讨论和增强请求。

答案 2 :(得分:0)

可能你可以查看/proc/[pid]/status

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

  

Cpus_allowed:可以运行此进程的CPU掩码

     

Cpus_allowed_list:与之前相同,但采用“列表格式”