Следующий фрагмент кода Android создает только собственные потоки, работающие на том же ядре ЦП. FaceEngineWrapper.Run()
- это JNI-оболочка для механизма определения лиц, которая порождает довольно много собственных потоков (через std :: thread и openmp в OpenCV-dnn). Но эти собственные потоки в конечном итоге работают на одном и том же ядре процессора, и весь процесс работает очень медленно.
Итак, как заставить собственные потоки использовать все ядра процессора?
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. Это приложение протестировано на плате Android RK3399, 2/4 большой / литр ядро. Приложение с jni shared lib потребляет 16-17% ЦП, а автономный исполняемый бинарный файл с тем же кодом и привилегиями root потребляет 34-35% ЦП. Если я включу некоторые дополнительные функции, загрузка процессора возрастет до 60% для двоичного файла, и это приложение по-прежнему будет работать с 17% процессором, в то время как весь сложный процесс становится намного медленнее. Так что я думаю, что использование этого приложения каким-то образом ограничено.
P.P.S. Проблема в сродстве с процессором. Я получил маску установленного CPU 000001 на этом 6-ядерном процессоре. Но по sched_setaffinity
до 111111 ничего не изменилось и ошибки не было возвращено. Мне действительно интересно, почему привязка к процессору неявно установлена здесь и что я могу сделать, чтобы отключить ее.
SetCpuAffinity({0,1})
- это код C ++, вызываемый в рабочем потоке (созданный std::thread
в Run
). sched_setaffinity
возвращает 0. Но sched_getaffinity
показывает 000001
впоследствии. Я не могу использовать pthread для этого, потому что в Android pthread lib нет функции привязки.
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();
}