CPU usage of the APP

How to get the CPU usage: When an application is running as a process, it contains several different threads. If we can get the CPU usage of all the threads in the application, we can also get the CPU usage of the application

IOS is based on the Apple Darwin kernel and consists of kernel, XNU, and Runtime. XNU is the Darwin kernel, which is short for “X is not UNIX” and is a hybrid kernel made up of a Mach microkernel and BSD. The Mach kernel is a lightweight platform that performs only the most basic functions of an operating system, such as processes and threads, virtual memory management, task scheduling, process communication, and messaging mechanisms. Other work, such as file manipulation and device access, is done by the BSD layer

Similar to Mac OS X, iOS threading technology is based on Mach threading technology, where the thread_basic_info structure provides basic thread information

struct thread_basic_info {
        time_value_t    user_time;      /* user run time */
        time_value_t    system_time;    /* system run time */
        integer_t       cpu_usage;      /* scaled cpu usage percentage */
        policy_t        policy;         /* scheduling policy in effect */
        integer_t       run_state;      /* run state (see below) */
        integer_t       flags;          /* various flags (see below) */
        integer_t       suspend_count;  /* suspend count for thread */
        integer_t       sleep_time;     /* number of seconds that thread
                                           has been sleeping */
};
Copy the code

A Mach task can be viewed as an abstraction of a machine-independent thread execution environment. A Task contains a list of its threads. The kernel provides a task_Threads API call to get the list of threads for a given task. You can then query information about a given thread using the thread_info API call, defined in thread_act.h

kern_return_t task_threads (
    task_t target_task,
    thread_act_array_t *act_list,
    mach_msg_type_number_t *act_listCnt
);
Copy the code

Task_threads stores all threads in the target_Task in an act_list array containing act_listCnt entries.

kern_return_t thread_info
(
	thread_act_t target_act,
	thread_flavor_t flavor,
	thread_info_t thread_info_out,
	mach_msg_type_number_t *thread_info_outCnt
);
Copy the code

Thread_info Queries the thread information specified in the flavor and returns the information to the thread_info_OUT cache, which is thread_info_outCnt bytes in length

The implementation of obtaining the CPU usage of the current application is as follows:

#import <mach/mach.h> #import <assert.h> + (CGFloat)appCpuUsage { task_info_data_t tinfo; mach_msg_type_number_t task_info_count = TASK_INFO_MAX; /// THREAD_BASIC_INFO. This type returns basic information about the thread, defined in the thread_basic_info_t structure, including user and system runtime. Kern_return_t kr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count); if (kr ! = KERN_SUCCESS) { return -1; } thread_array_t thread_list; mach_msg_type_number_t thread_count; thread_info_data_t thinfo; mach_msg_type_number_t thread_info_count; thread_basic_info_t basic_info_th; Kr = task_threads(mach_task_self(), &thread_list, &thread_count); if (kr ! = KERN_SUCCESS) { return -1; } long total_time = 0; long total_userTime = 0; CGFloat total_cpu = 0; int j; // for each thread for (j = 0; j < (int)thread_count; j++) { thread_info_count = THREAD_INFO_MAX; kr = thread_info(thread_list[j], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count); if (kr ! = KERN_SUCCESS) { return -1; } basic_info_th = (thread_basic_info_t)thinfo; if (! (basic_info_th->flags & TH_FLAGS_IDLE)) { total_time = total_time + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds; total_userTime = total_userTime + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds; total_cpu = total_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * kMaxPercent; Kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t)); assert(kr == KERN_SUCCESS); return total_cpu; }Copy the code

Number of CPU cores

+ (NSUInteger)cpuNumber {
    return [NSProcessInfo processInfo].activeProcessorCount;
}
Copy the code

CPU frequency

CPU frequency is the clock frequency of the CPU. It is the working frequency (the number of synchronization pulses occurring in 1 second) of the CPU operation. The unit is Hz, which determines the speed of the mobile device. In iOS, there are three performance indicators related to CPU frequency: CPU frequency, maximum CPU frequency, and minimum CPU frequency.

+ (NSUInteger)getSysInfo:(uint)typeSpecifier {
    size_t size = sizeof(int);
    int results;
    int mib[2] = {CTL_HW, typeSpecifier};
    sysctl(mib, 2, &results, &size, NULL, 0);
    return (NSUInteger)results;
}

+ (NSUInteger)getCpuFrequency {
    return [self getSysInfo:HW_CPU_FREQ];
}
Copy the code