如何确定Java线程运行在哪个核心上?
我想实现一个CoreLocal映射,它的工作原理与ThreadLocal一样,只是它返回一个特定于当前线程运行的核心的值如何确定Java线程运行在哪个核心上?,java,multithreading,performance,core,Java,Multithreading,Performance,Core,我想实现一个CoreLocal映射,它的工作原理与ThreadLocal一样,只是它返回一个特定于当前线程运行的核心的值 这样做的原因是,我想编写代码,从队列中获取作业,但我想优先考虑那些关联数据已经与从队列中拾取作业的线程位于同一个一级缓存中的作业。因此,我希望每个核心都有一个队列,而不是整个程序的一个作业队列。只有当队列为空时,工作线程才会查看其他核心的队列。可能您可以检查/proc/[pid]/status 以下字段可能会有所帮助: 允许的CPU:可运行此进程的CPU的掩码 允许的CPU列
这样做的原因是,我想编写代码,从队列中获取作业,但我想优先考虑那些关联数据已经与从队列中拾取作业的线程位于同一个一级缓存中的作业。因此,我希望每个核心都有一个队列,而不是整个程序的一个作业队列。只有当队列为空时,工作线程才会查看其他核心的队列。可能您可以检查
/proc/[pid]/status
以下字段可能会有所帮助:
允许的CPU:可运行此进程的CPU的掩码
允许的CPU列表:与上一个相同,但采用“列表格式”
有一个相关问题没有令人满意的答案(解析top
输出不起作用,并且接受的答案不再有效)。我以为
/proc/<pid>/task/<tid>/sched
但是在运行4.4.0-92-generic内核的i5-2400上,这一行对于所有线程都是相同的。我猜,“节点”意味着一个完整的CPU(套接字),而我只有一个
我找不到这方面的文档,或者在中遗漏了它
但是,我担心,获得这些信息可能会对您产生不太可能的帮助:
- 从proc文件系统读取数据的成本可能太高了
- 与
不同,您的ThreadLocal
不是线程安全的:将线程迁移到另一个核心可能会破坏一些琐碎的非原子操作,如CoreLocal
。暂停也可以。所以,你需要一些原子或线程本地人来让它工作,这可能再次使它太慢,你想要的someCoreLocalField++
getcpu
是在VDSO中实现的,没有内核转换,因此它应该只需要几纳秒,再加上JNI调用需要几纳秒。JNA比较慢
如果您确实需要速度,您可以随时将该函数作为一个内在函数添加到定制的JVM中(因为OpenJDK是开源的)。这将节省更多的纳秒
请记住,这些信息一经获得就可能过时,因此您永远不应该依赖于它的正确性,而应该依赖于它的性能。由于您已经需要处理获取“错误”值的问题,另一种可能的方法是将CPU ID的缓存值存储在ThreadLocal
中,并且只定期更新它。这使得诸如解析/proc
文件系统之类的缓慢方法变得可行,因为您很少这样做。为了获得最大的速度,您可以定期从计时器线程使本地线程失效,而不是在每次调用时检查失效条件
1强烈建议阅读讨论和增强请求 听起来你的纳秒数真的很低。你能保证线程在从队列中获取作业后不会被重新调度到另一个内核,从而使所有这些机制都适得其反吗?Q==队列!将线程保持在具有热缓存的内核上比纳秒()更有价值。我不知道线程可以跳过内核的频率或事件,但您必须假设存在某种关联,否则缓存根本不起作用。@gregw我想知道,您是否可以在
CoreLocal
方面取得一些进展,或者它是如何最终解决的。这不是问题
current_node=0, numa_group_id=0