【发布时间】:2019-01-10 10:53:20
【问题描述】:
以下 Android 代码仅生成在同一 CPU 内核上运行的本机线程。 FaceEngineWrapper.Run() 是用于面部检测推理引擎的 JNI 包装器,并产生了很多本地线程(通过 OpenCV-dnn 中的 std::thread 和 openmp)。但这些原生线程最终运行在同一个 CPU 内核上,整个进程运行速度非常慢。
那么如何让原生线程利用所有 CPU 内核呢?
Observable.create(new ObservableOnSubscribe<Boolean>() {
@Override
public void subscribe(ObservableEmitter<Boolean> e) throws Exception {
e.onNext(true);
getFrameBitmap();
e.onComplete();
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
mFaceEngineWrapper.Run();
}
}).start();
}
});
附:此应用程序在 Android RK3399 板上测试,2/4 大/小核心。具有 jni 共享库的应用程序消耗 16-17% 的 cpu,具有相同代码和 root 权限的独立可执行二进制文件消耗 34-35% 的 cpu。如果我启用了一些额外的功能,二进制的 cpu 使用率会达到大约 60%,而这个应用程序仍然以 17% 的 cpu 运行,而整个删除过程会变得慢得多。所以我猜这个应用程序的cpu使用率受到了某种限制。
附言问题是关于 cpu 亲和力。我在这个 6 核 CPU 上获得了 CPU 设置掩码 000001。但是sched_setaffinity 到 111111 没有任何改变,也没有返回错误。我真的很想知道为什么在这里隐式设置 CPU 亲和性以及我可以做些什么来禁用它。
SetCpuAffinity({0,1}) 是在工作线程中调用的 C++ 代码(由std::thread 在Run 创建)。 sched_setaffinity 返回 0。但 sched_getaffinity 之后显示 000001。我不能使用 pthread 来做,因为 Android 的 pthread 库不提供亲和功能。
void SetCpuAffinity(const std::vector<int32_t>& cpuids) {
int32_t nproc = sysconf(_SC_NPROCESSORS_ONLN);
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
for (auto&& cpuid: cpuids) {
if (cpuid >= nproc || cpuid < 0) {
LOG_ERROR("cannot set affinity cpu id to " << cpuid << " total cpu " << nproc);
}
CPU_SET(cpuid, &cpu_set);
}
int32_t res = sched_setaffinity(gettid(), sizeof(cpu_set_t), &cpu_set);
LOG_INFO("try to set thread cpu affinity, res "<< res << ", errno " << errno);
TestThreadAffinity();
TestThreadCpu();
}
【问题讨论】:
-
您是否有理由需要
new Thread而不是使用线程池? -
availableProcessors() 返回什么数字?完全取决于 Android 告诉你的东西比你实际拥有的要少,而且你不能只用 Java 代码做任何事情。
-
你怎么知道所有这些线程都在同一个内核上运行?
-
@KarolDowbecki C++ 代码将管理自己的线程。 Java 中的线程似乎无关紧要。
-
@PavelZdenek 我正在使用 2/4 大/小核心臂设备。工作线程由 c++ std::thread 创建。 Java 代码在 c++ 中基本上充当
main。
标签: java android multithreading java-native-interface affinity