The following piece of Android code only produces native threads running on the same CPU core. FaceEngineWrapper.Run() is a JNI wrapper for a face detect inference engine and spawns quite a lot native threads (through both std::thread and openmp in OpenCV-dnn). But these native threads end up running on the same CPU core and the whole process runs very slow.
So how to make native threads utilize all CPU cores?
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();
}
});
P.S. This app is tested on an Android RK3399 board, 2/4 big/litte core. The app with jni shared lib consumes 16-17% cpu and the standalone executable binary with same code and root priviledge consumes 34-35% cpu. If I enable some extra features, the cpu usage goes to about 60% for binary and this app still runs at 17% cpu while the whole delecting process gets much slower. So I guess this app's cpu usage is somehow restricted.
P.P.S. The problem is about cpu affinity. I got CPU-set mask 000001 on this 6-core CPU. But by sched_setaffinity to 111111 nothing changed and no error was returned. I really wonder why CPU affinity is set implicitly here and what I can do to disable it.
SetCpuAffinity({0,1}) is the C++ code called in the working thread (created by std::thread in Run). sched_setaffinity returns 0. But sched_getaffinity shows 000001 afterwards. I can't use pthread to do it because Android's pthread lib does not provide affinity function.
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 Threadinstead of using a thread pool? - Karol Dowbeckimainin c++. - reasonsolo