設計網(wǎng)站私單價格草根seo博客
有時候為了降低App算力占用,會把關鍵的線程綁定到大核中,下面介紹一種綁核的方式
查看綁核
-
查看pid
:/ # ps -A | grep test u0_a15 25178 405 15950272 176544 do_epoll_wait 0 S com.test.jnites
-
查看線程號
top -H -p 25178 25224 u0_a15 20 0 15G 172M 82M R 83.3 1.6 4:17.53 JNI_Test com.test.jnitest 25229 u0_a15 10 -10 15G 172M 82M S 0.0 1.6 0:00.00 AdrenoOsLib com.test.jnitest 25221 u0_a15 10 -10 15G 172M 82M S 0.0 1.6 0:00.03 RenderThread com.test.jnitest
可以獲取到JNI_Test線程號25224
-
查看綁核情況
:/ # taskset -p 30692 pid 30692's current affinity mask: ff
結果顯示為 FF,則表示當前進程已綁定到所有的可用核心。這是因為在 taskset 命令中,每個核心使用一個位來表示,1 表示該核心被綁定,0 表示未被綁定。因此,FF 的二進制表示為 11111111,表示所有的核心都被綁定。
綁核
通過 Java 代碼調用 sched_setaffinity 函數(shù)來實現(xiàn)線程或進程的核心綁定。需要注意的是,在 Java 中并沒有直接暴露 sched_setaffinity 函數(shù),需要使用 JNI(Java Native Interface)來調用 C/C++ 代碼中的相應函數(shù)。
以下是一個簡單的示例,展示了如何使用 JNI 和 sched_setaffinity 函數(shù)來將當前線程與指定的 CPU 核心綁定。首先在 C/C++ 代碼中實現(xiàn)核心綁定函數(shù),然后在 Java 代碼中調用該函數(shù):
-
JAVA
class TestLib {companion object{init {System.loadLibrary("jnitest")}}external fun setAffinity(core_id: Int): Int}
-
C++
#include <jni.h>#include <string>#include <thread>#include <sched.h>#include <unistd.h>extern "C"JNIEXPORT jint JNICALLJava_com_test_jnitest_TestLib_setAffinity(JNIEnv *env, jobject thiz, jint core_id) {cpu_set_t cpuset;CPU_ZERO(&cpuset);CPU_SET(core_id, &cpuset);pid_t pid = getpid();if (sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset) == -1) {return -1; // 設置失敗}return 0; // 設置成功}
-
測試調用
var testThread = Thread{var ret = testLib.setAffinity(3)Log.i(TAG,"ret = ${ret}")while (true){}}testThread.name = "JNI_Test"testThread.start()
運行后查看
:/ # taskset -p 8599pid 8599's current affinity mask: 8
發(fā)現(xiàn)主線程綁定到了第三個核上,8是0000 1000,如果要是綁定子線程的話需要修改sched_setaffinity第一個參數(shù)改為0,再運行后
:/ # ps -A | grep testu0_a15 10010 405 15939516 143716 do_epoll_wait 0 S com.test.jnitest:/ # taskset -p 10010pid 10010's current affinity mask: ff:/ # taskset -p 10040pid 10040's current affinity mask: 8
子線程成功綁定到了第三個核