Ядра процессоров Android представлены в /proc/stat

Я разрабатываю приложение для Android, которое показывает загрузку процессора на ядро ​​и потребление памяти. Для загрузки процессора я читаю / proc / stat, а для памяти -> /proc/meminfo. Однако я вижу, что количество ядер ЦП в / proc / stat меняется при последующем чтении файла.

cpu 230599 10622 84595 1892023 8236 16 285 0 0 0 cpu0 138005 7992 58080 1738918 6407 16 278 0 0 0 intr 9136791 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9601 0 0 0 0 0 0 ....... ctxt 16904510 btime 1394641996 processes 16919 procs_running 2 procs_blocked 0 softirq 1688530 407 706934 422 1558 407 407 92978 324500 1267 559650

и через 5 секунд он становится:

cpu 230772 10623 84671 1890801 8236 16 286 0 0 0 cpu0 138104 7993 58126 1739267 6407 16 279 0 0 0 cpu1 92668 2630 26545 151534 1829 0 7 0 0 0 intr 9144729 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9601 0 0 0 0 0 0 ........ ctxt 16923744 btime 1394641996 processes 16946 procs_running 2 procs_blocked 0 softirq 1690205 407 707396 422 1558 407 407 93311 324790 1267 560240

Значит ли это, что ядра процессора спят в некоторых случаях?

5 ответов

Решение

Я знаю, что это старо, но, кажется, нет ответа на это, и я также искал решение.

Я понял, что если я записываю каждое ядро ​​с именем "cpu", которое следует за номером. и процессор идет от 0-3. И если я читаю ядра по порядку. Затем, если.readline() из /proc/stat возвращает строку, которая НЕ содержит процессор, тогда это ядро ​​не должно работать и находится в автономном режиме. Таким образом, теоретически, это будет при нулевом проценте использования. Итак, верните 0.

* Завершенный ответ с кодом, см. Ниже *

Вот какой-то код, в случае, если то, что я сказал, не имело смысла, мой основан на этом: Получить использование памяти в Android

и вот как я нашел новый расчет, который дал мне более точное представление о показаниях ядра: как получить общее использование процессора в Linux (C++)

Во-первых, вот некоторые из моих функций процессора, которые отображают строку после этих циклов и прочее для пользователя. Я публикую это, чтобы вы лучше поняли меня, и что означает мой код

float[] coreValues = new float[10];
                //get how many cores there are from function
                int numCores = getNumCores();
                for(byte i = 0; i < numCores; i++)
                {
                    coreValues[i] = readCore(i);
                }

getNumCores можно найти здесь, я не буду публиковать, потому что я чувствую, что человек, который это сделал, должен получить за это кредит: как вы можете обнаружить двухъядерный процессор на устройстве Android из кода?

И, наконец, вот мой код, надеюсь, он имеет смысл, и я предложил много комментариев.

//for multi core value
        private float readCore(int i) 
        {
            /*
             * how to calculate multicore
             * this function reads the bytes from a logging file in the android system (/proc/stat for cpu values)
             * then puts the line into a string
             * then spilts up each individual part into an array
             * then(since he know which part represents what) we are able to determine each cpu total and work
             * then combine it together to get a single float for overall cpu usage
             */
            try {
                RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
                //skip to the line we need
                for(int ii = 0; ii < i + 1; ++ii)
                {
                    reader.readLine();
                }
                String load = reader.readLine();

                //cores will eventually go offline, and if it does, then it is at 0% because it is not being
                //used. so we need to do check if the line we got contains cpu, if not, then this core = 0
                if(load.contains("cpu"))
                {
                String[] toks = load.split(" ");

                //we are recording the work being used by the user and system(work) and the total info
                //of cpu stuff (total)
                //https://stackru.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438

                long work1 = Long.parseLong(toks[1])+ Long.parseLong(toks[2]) + Long.parseLong(toks[3]);
                long total1 = Long.parseLong(toks[1])+ Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + 
                        Long.parseLong(toks[4]) + Long.parseLong(toks[5])
                      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

                try 
                {
                    //short sleep time = less accurate. But android devices typically don't have more than
                    //4 cores, and I'n my app, I run this all in a second. So, I need it a bit shorter
                    Thread.sleep(200);
                } 
                catch (Exception e) {}

                reader.seek(0);
                //skip to the line we need
                for(int ii = 0; ii < i + 1; ++ii)
                {
                    reader.readLine();
                }
                load = reader.readLine();
              //cores will eventually go offline, and if it does, then it is at 0% because it is not being
                //used. so we need to do check if the line we got contains cpu, if not, then this core = 0%
                if(load.contains("cpu"))
                {
                    reader.close();
                    toks = load.split(" ");

                    long work2 = Long.parseLong(toks[1])+ Long.parseLong(toks[2]) + Long.parseLong(toks[3]);
                    long total2 = Long.parseLong(toks[1])+ Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + 
                            Long.parseLong(toks[4]) + Long.parseLong(toks[5])
                          + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);



                    //here we find the change in user work and total info, and divide by one another to get our total
                    //seems to be accurate need to test on quad core
                    //https://stackru.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438

                    return (float)(work2 - work1) / ((total2 - total1));
                }
                else
                {
                    reader.close();
                    return 0;
                }

                }
                else
                {
                    reader.close();
                    return 0;
                }

            } 
            catch (IOException ex) 
            {
                ex.printStackTrace();
            }

            return 0;
        } 

И, как последнее замечание, моя функция readCore вернет значение 0,0 - 1,0, вам нужно умножить на 100, чтобы получить процент.

РЕДАКТИРОВАТЬ В соответствии с требованиями комментариев ниже, документация Android: "Пока активные процессоры могут быть подключены к сети или переведены в автономный режим, изменить тактовые частоты и связанные напряжения (возможно, также влияющие на скорости шины памяти и другое состояние питания ядра системы), и может перейти на более низкое энергопотребление. состояния бездействия, находящиеся в цикле бездействия ядра. Эти различные состояния мощности ЦП измеряются не только для профиля мощности, но и при измерении других параметров может быть необходимо избежать отклонения потребления мощности ".

Ссылка: https://source.android.com/devices/tech/power.html

Ответы @Torch2424 и @Andre в порядке, но для моего использования им не хватает нескольких вещей:

  • Я не хочу спать между двумя опросами. Я предпочитаю использовать процессор с момента последнего вызова функции и решать где-либо еще, когда вызывать функцию cpuusage.
  • Я думаю, что существует ошибка в подсчете использования ядер: когда ядро ​​отключается, оно не всегда присваивает результат ядра правильному расположению предыдущего массива ядра.
  • Мне нужна функция, которая возвращает глобальное использование процессора.

Вот код, который, мы надеемся, исправит это правильно: доступен как класс или как простое приложение.

Даже если принятый ответ был дан через несколько месяцев после вопроса, он был очень полезен для меня. Надеюсь, мое предложение будет полезным для всех, кто будет читать этот вопрос в будущем.
Ответ @Torch2424 был очень хорошим, но не прошел проверку: как вы сказали, иногда Android не использует все процессоры; Я попробовал ваш код на 4-ядерном планшете и действительно вижу, что большую часть времени 2 ЦП вообще не используются или меняются не так часто, поэтому относительные строки файла /proc/stat точно такие же. Это означает, что (total2 - total1) равно 0, а затем вы пытаетесь разделить на 0, в результате чего NaN.
На самом деле это мой рабочий код для функции readCore():

// for multi core value
private float readCore(int i) {
    /*
     * how to calculate multicore this function reads the bytes from a
     * logging file in the android system (/proc/stat for cpu values) then
     * puts the line into a string then spilts up each individual part into
     * an array then(since he know which part represents what) we are able
     * to determine each cpu total and work then combine it together to get
     * a single float for overall cpu usage
     */
    try {
        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        // skip to the line we need
        for (int ii = 0; ii < i + 1; ++ii) {
            String line = reader.readLine();            
        }
        String load = reader.readLine();

        // cores will eventually go offline, and if it does, then it is at
        // 0% because it is not being
        // used. so we need to do check if the line we got contains cpu, if
        // not, then this core = 0
        if (load.contains("cpu")) {
            String[] toks = load.split(" ");

            // we are recording the work being used by the user and
            // system(work) and the total info
            // of cpu stuff (total)
            // http://stackru.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438

            long work1 = Long.parseLong(toks[1]) + Long.parseLong(toks[2])
                    + Long.parseLong(toks[3]);
            long total1 = Long.parseLong(toks[1]) + Long.parseLong(toks[2])
                    + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                    + Long.parseLong(toks[5]) + Long.parseLong(toks[6])
                    + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

            try {
                // short sleep time = less accurate. But android devices
                // typically don't have more than
                // 4 cores, and I'n my app, I run this all in a second. So,
                // I need it a bit shorter
                Thread.sleep(300);
            } catch (Exception e) {
            }

            reader.seek(0);
            // skip to the line we need
            for (int ii = 0; ii < i + 1; ++ii) {
                reader.readLine();
            }
            load = reader.readLine();

            // cores will eventually go offline, and if it does, then it is
            // at 0% because it is not being
            // used. so we need to do check if the line we got contains cpu,
            // if not, then this core = 0%
            if (load.contains("cpu")) {
                reader.close();
                toks = load.split(" ");

                long work2 = Long.parseLong(toks[1]) + Long.parseLong(toks[2])
                        + Long.parseLong(toks[3]);
                long total2 = Long.parseLong(toks[1]) + Long.parseLong(toks[2])
                        + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                        + Long.parseLong(toks[5]) + Long.parseLong(toks[6])
                        + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

                // here we find the change in user work and total info, and
                // divide by one another to get our total
                // seems to be accurate need to test on quad core
                // http://stackru.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-c/3017438#3017438

                 if ((total2 - total1) == 0)
                     return 0;
                 else 
                     return (float) (work2 - work1) / ((total2 - total1));

            } else {
                reader.close();
                return 0;
            }

        } else {
            reader.close();
            return 0;
        }

    } catch (IOException ex) {
        ex.printStackTrace();
    }

    return 0;
}

Надеюсь, поможет!

Я искал о том, как получить CPU использование от Android для дней и ночей, и я сталкиваюсь с этой проблемой несколько раз.

Ну, если я не ошибаюсь, я думаю, что когда вы не получите CPU Ядро означает, что ядро, которое не отображается, находится в автономном режиме (Android делает это, чтобы не допустить чрезмерного разряда батареи).

Если вы хотите выяснить, сколько ядер у андроида, найдите другой путь, есть тамошние, а затем делайте что хотите.

Надеюсь, это сработает для вас ...

      public static float cpuTemperature() {
    Process process;
    try {
        process = Runtime.getRuntime().exec("cat sys/class/thermal/thermal_zone0/temp");
        process.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        if (line != null) {
            float temp = Float.parseFloat(line);
            return temp / 1000.0f;
        } else {
            return 45.0f;
        }
    } catch (Exception e) {
        e.printStackTrace();
        return 0.0f;
    }
}
Другие вопросы по тегам