Android通过setaffinity实现绑核

有时候为了降低App算力占用,会把关键的线程绑定到大核中,下面介绍一种绑核的方式

查看绑核

  1. 查看pid

    :/ # ps -A | grep test
    u0_a15        25178    405 15950272 176544 do_epoll_wait      0 S com.test.jnites
    
  2. 查看线程号

    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

  3. 查看绑核情况

    :/ # taskset -p 30692
    pid 30692's current affinity mask: ff
    

    结果显示为 FF,则表示当前进程已绑定到所有的可用核心。这是因为在 taskset 命令中,每个核心使用一个位来表示,1 表示该核心被绑定,0 表示未被绑定。因此,FF 的二进制表示为 11111111,表示所有的核心都被绑定。

绑核

通过 Java 代码调用 sched_setaffinity 函数来实现线程或进程的核心绑定。需要注意的是,在 Java 中并没有直接暴露 sched_setaffinity 函数,需要使用 JNI(Java Native Interface)来调用 C/C++ 代码中的相应函数。
以下是一个简单的示例,展示了如何使用 JNI 和 sched_setaffinity 函数来将当前线程与指定的 CPU 核心绑定。首先在 C/C++ 代码中实现核心绑定函数,然后在 Java 代码中调用该函数:

  1. JAVA

     class TestLib {
         companion object{
             init {
                 System.loadLibrary("jnitest")
             }
         }
         external fun setAffinity(core_id: Int): Int
     }
    
  2. C++

     #include <jni.h>
     #include <string>
     #include <thread>
     #include <sched.h>
     #include <unistd.h>
     
     extern "C"
     JNIEXPORT jint JNICALL
     Java_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; // 设置成功
     }
    
  3. 测试调用

     var testThread = Thread{
         var ret = testLib.setAffinity(3)
         Log.i(TAG,"ret = ${ret}")
         while (true){
         }
     }
     testThread.name = "JNI_Test"
     testThread.start()
    

    运行后查看

     :/ # taskset -p 8599
     pid 8599's current affinity mask: 8
    

    发现主线程绑定到了第三个核上,8是0000 1000,如果要是绑定子线程的话需要修改sched_setaffinity第一个参数改为0,再运行后

     :/ # ps -A | grep test
     u0_a15        10010    405 15939516 143716 do_epoll_wait      0 S com.test.jnitest
     :/ # taskset -p 10010
     pid 10010's current affinity mask: ff
     :/ # taskset -p 10040
     pid 10040's current affinity mask: 8
    

    子线程成功绑定到了第三个核

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值