我想实现一个CoreLocal映射,它就像ThreadLocal一样工作,只返回一个特定于当前线程运行的核心的值。
这样做的原因是我想编写将从队列中获取作业的代码,但我想优先考虑那些将其关联数据放在与挑选作业的线程相同的L1缓存中的作业从队列中。因此,我想为整个程序创建一个队列,而不是每个核心都有一个队列,只有当队列为空时,工作线程才会查看其他核心的队列。
答案 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中错过了它。
但是,我担心获取此信息可能会对您造成不可避免的帮助:
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:与之前相同,但采用“列表格式”