3

我正在编写一个使用密集型 CPU 和内存的多线程 Java 程序。该程序的目标是在图上执行一些算法。该程序在运行 linux 的 NUMA 机器上执行,我希望获得最佳性能。

为此,我为每个 NUMA 节点制作了多个图形副本,以便每个线程都能够访问本地内存上的图形。

本地内存分配的部分已经通过在分配图的每个新副本之前设置亲和性来完成。这是用 jna 完成的,所以如果可能的话,我更愿意继续使用这个库而不是添加 jni 代码。

我的问题是如何检查工作线程正在运行哪个内核以便从本地内存中读取?

我了解线程到核心的绑定在执行期间可能会发生变化。但是,内核尝试在所有时间片上在同一个 NUMA 节点上运行线程。因此,仅在开始时检查线程在哪个内核上运行对于大多数情况都有效。

4

3 回答 3

3

事实证明,有一种方法可以通过 jna 调用来获取所需的信息。方法名称是:sched_getcpu. 完整的代码片段如下所示

public interface CLibrary extends Library{
    public static final CLibrary INSTANCE = 
           (CLibrary) Native.loadLibrary("c", CLibrary.class);
    public int sched_getcpu() throws LastErrorException;
}

现在,当你制作

CLibrary.INSTANCE.sched_getcpu();

您将获得当前线程正在运行的核心 id。

于 2014-05-26T11:08:59.783 回答
1

我发现完成上述任务的最简单方法是运行 shell 命令并解析输出。

鉴于我知道当前线程的进程 id 和线程 id(可通过 jna 实现),我运行以下命令:

ps -p <pid> -L -o tid,psr | grep <tid>

结果是一行有两个数字,第一个是线程 id,第二个是该线程正在执行的核心 id。

在一个循环中,我将线程关联设置到不同的内核,并检查了上述命令的输出。输出总是正确的。

于 2014-05-24T20:56:49.473 回答
0

您在谈论的是线程亲和力。也许这会有所帮助。

Java 线程亲和性

如果不涵盖它,您需要做的另一件事是使用本机代码来确定哪个核心位于哪个 numa 上。

于 2014-05-22T01:23:04.613 回答