Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何测量iOS线程的实际CPU时间?_Objective C_Ios_Multithreading_Profiling_Pthreads - Fatal编程技术网

Objective c 如何测量iOS线程的实际CPU时间?

Objective c 如何测量iOS线程的实际CPU时间?,objective-c,ios,multithreading,profiling,pthreads,Objective C,Ios,Multithreading,Profiling,Pthreads,我正在寻找用于Android、Microsoft或Posix的iOS模拟程序和函数,以测量多线程应用程序中函数使用的实际“清除”时间。也就是说,我不想测量函数中实际的挂钟时间,而是CPU时间 我发现关于这一点的讨论很有趣。不幸的是,两者都不适用于iOS iOS上有类似的函数吗?从它的描述来看,clock()函数似乎满足了您的需要 如果有人在寻找一个好答案: 不久前,我在中发现了一些很棒的代码(用于在OSX中查找CPU时间/内存使用情况),并对其进行了一些修改。我用它来测试ARM上的一些NEON优

我正在寻找用于Android、Microsoft或Posix的iOS模拟程序和函数,以测量多线程应用程序中函数使用的实际“清除”时间。也就是说,我不想测量函数中实际的挂钟时间,而是CPU时间

我发现关于这一点的讨论很有趣。不幸的是,两者都不适用于iOS


iOS上有类似的函数吗?

从它的描述来看,clock()函数似乎满足了您的需要


如果有人在寻找一个好答案:

不久前,我在中发现了一些很棒的代码(用于在OSX中查找CPU时间/内存使用情况),并对其进行了一些修改。我用它来测试ARM上的一些NEON优化。您可能只需要获取当前线程时间的部分

#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/mach_port.h>
#include <mach/mach_traps.h>
#include <mach/task_info.h>
#include <mach/thread_info.h>
#include <mach/thread_act.h>
#include <mach/vm_region.h>
#include <mach/vm_map.h>
#include <mach/task.h>


typedef struct {
    double utime, stime;
} CPUTime;

int get_cpu_time(CPUTime *rpd, bool_t thread_only)
{
    task_t task;
    kern_return_t error;
    mach_msg_type_number_t count;
    thread_array_t thread_table;
    thread_basic_info_t thi;
    thread_basic_info_data_t thi_data;
    unsigned table_size;
    struct task_basic_info ti;

    if (thread_only) {
        // just get time of this thread
        count = THREAD_BASIC_INFO_COUNT;
        thi = &thi_data;
        error = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)thi, &count);
        rpd->utime = thi->user_time.seconds + thi->user_time.microseconds * 1e-6;
        rpd->stime = thi->system_time.seconds + thi->system_time.microseconds * 1e-6;
        return 0;
    }


    // get total time of the current process

    task = mach_task_self();
    count = TASK_BASIC_INFO_COUNT;
    error = task_info(task, TASK_BASIC_INFO, (task_info_t)&ti, &count);
    assert(error == KERN_SUCCESS);
    { /* calculate CPU times, adapted from top/libtop.c */
        unsigned i;
        // the following times are for threads which have already terminated and gone away
        rpd->utime = ti.user_time.seconds + ti.user_time.microseconds * 1e-6;
        rpd->stime = ti.system_time.seconds + ti.system_time.microseconds * 1e-6;
        error = task_threads(task, &thread_table, &table_size);
        assert(error == KERN_SUCCESS);
        thi = &thi_data;
        // for each active thread, add up thread time
        for (i = 0; i != table_size; ++i) {
            count = THREAD_BASIC_INFO_COUNT;
            error = thread_info(thread_table[i], THREAD_BASIC_INFO, (thread_info_t)thi, &count);
            assert(error == KERN_SUCCESS);
            if ((thi->flags & TH_FLAGS_IDLE) == 0) {
                rpd->utime += thi->user_time.seconds + thi->user_time.microseconds * 1e-6;
                rpd->stime += thi->system_time.seconds + thi->system_time.microseconds * 1e-6;
            }
            error = mach_port_deallocate(mach_task_self(), thread_table[i]);
            assert(error == KERN_SUCCESS);
        }
        error = vm_deallocate(mach_task_self(), (vm_offset_t)thread_table, table_size * sizeof(thread_array_t));
        assert(error == KERN_SUCCESS);
    }
    if (task != mach_task_self()) {
        mach_port_deallocate(mach_task_self(), task);
        assert(error == KERN_SUCCESS);
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类型定义结构{
双倍使用时间;
}CPUTime;
int get_cpu_时间(仅限CPUTime*rpd、bool_t线程)
{
任务任务;
内核返回错误;
马赫数、信号类型、数量、计数;
线程数组线程表;
线程基本信息;
线程\u基本信息\u数据\u该数据;
无符号表格大小;
结构任务\基本\信息ti;
如果(仅螺纹){
//只需获取此线程的时间
计数=线程\基本\信息\计数;
thi=&thi_数据;
错误=线程信息(马赫线程自身()、线程基本信息、(线程信息)thi和计数);
rpd->utime=thi->user\u time.seconds+thi->user\u time.microseconds*1e-6;
rpd->stime=thi->system_time.seconds+thi->system_time.microsonds*1e-6;
返回0;
}
//获取当前进程的总时间
task=mach_task_self();
计数=任务\基本\信息\计数;
错误=任务信息(任务、任务基本信息、(任务信息)&ti和计数);
断言(error==KERN_SUCCESS);
{/*计算CPU时间,根据top/libtop.c改编*/
未签名的i;
//以下时间适用于已经终止并离开的线程
rpd->utime=ti.user\u time.seconds+ti.user\u time.microsonds*1e-6;
rpd->stime=ti.system\u time.seconds+ti.system\u time.microsonds*1e-6;
错误=任务线程(任务、线程表和表大小);
断言(error==KERN_SUCCESS);
thi=&thi_数据;
//对于每个活动线程,添加线程时间
对于(i=0;i!=表格大小;++i){
计数=线程\基本\信息\计数;
错误=线程信息(线程表[i]、线程基本信息、(线程信息)thi和计数);
断言(error==KERN_SUCCESS);
如果((thi->flags&TH_flags_IDLE)==0){
rpd->utime+=thi->user\u time.seconds+thi->user\u time.microseconds*1e-6;
rpd->stime+=thi->system_time.seconds+thi->system_time.microsonds*1e-6;
}
错误=mach_port_deallocate(mach_task_self(),thread_table[i]);
断言(error==KERN_SUCCESS);
}
错误=vm_释放(mach_task_self(),(vm_offset_t)thread_table,table_size*sizeof(thread_array_t));
断言(error==KERN_SUCCESS);
}
if(task!=mach_task_self()){
mach_port_deallocate(mach_task_self(),task);
断言(error==KERN_SUCCESS);
}
返回0;
}

我使用此代码测量线程CPU时间。它基于,但更加简洁和集中

线程时间
\ifndef线程时间\u h
#定义线程时间
#包括
typedef结构线程时间{
int64用户时间;
int64系统时间;
}线程时间;
线程时间线程时间();
线程时间线程时间子线程(线程时间常数a、线程时间常数b);
#endif/*线程时间*/
线程时间
#包括“thread\u time.h”
#包括
#包括
#包括
int64时间值到时间值(时间值常数){
返回(int64_t)t.秒*1000000+t.微秒;
}
线程时间线程时间(){
线程基本信息数据基本信息;
马赫数、型号、编号、计数=螺纹数、基本信息数;
kern\u return\u t const result=线程信息(mach\u thread\u self(),线程基本信息,(线程信息)&基本信息,&计数);
如果(结果==KERN_SUCCESS){
返回(线程时间){
.user\u time\u us=时间值\u到\u us(基本信息.user\u时间),
.system\u time\u us=时间\u值\u到\u us(基本信息.system\u时间)
};
}否则{
返回(线程时间){-1,-1};
}
}
线程时间线程时间子线程(线程时间常数a、线程时间常数b){
返回(线程时间){
.user\u time\u us=a.user\u time\u us-b.user\u time\u us,
.system\u time\u us=a.system\u time\u us-b.system\u time\u us
};
}

您只是在寻找精确的挂钟时间吗?如果是这样的话,这个问题的答案应该是有效的:@Brad Larson:不,我想测量与挂钟相反的时间,来测量给定线程使用的纯CPU时间。只是想检查一下:你真的需要在代码中加入这个吗?Instruments在不需要修改程序的情况下做得很好。Rob的观点是Instruments具有很强的功能,可以只在CPU上显示方法的执行时间(Shark也是如此,但Instruments更容易使用)。您也可以使用DTrace的
vtimestamp
,就像我在本文“时间配置”部分中所展示的那样:,但这只适用于在iOS模拟器中运行的应用程序,而不适用于实际设备。这很酷,但不幸的是,我的配置非常特定于ARM处理器,因此iOS模拟器与此无关。不幸的是,时钟()除了非常不准确外,还不能测量每个线程的时间。是的!这给了我们丢失的信息!!碰巧你有这样的linux/android版本吗?@JoelTeply这段代码使用Mach内核API,所以它是macOS及其衍生产品(iOS、watchOS、tvOS)特有的。不幸的是,我没有针对LinuxK的适应性
#ifndef thread_time_h
#define thread_time_h

#include <stdint.h>

typedef struct thread_time {
    int64_t user_time_us;
    int64_t system_time_us;
} thread_time_t;

thread_time_t thread_time();
thread_time_t thread_time_sub(thread_time_t const a, thread_time_t const b);

#endif /* thread_time_h */
#include "thread_time.h"
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/thread_info.h>

int64_t time_value_to_us(time_value_t const t) {
    return (int64_t)t.seconds * 1000000 + t.microseconds;
}

thread_time_t thread_time() {
    thread_basic_info_data_t basic_info;
    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
    kern_return_t const result = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count);
    if (result == KERN_SUCCESS) {
        return (thread_time_t){
            .user_time_us   = time_value_to_us(basic_info.user_time),
            .system_time_us = time_value_to_us(basic_info.system_time)
        };
    } else {
        return (thread_time_t){-1, -1};
    }
}

thread_time_t thread_time_sub(thread_time_t const a, thread_time_t const b) {
    return (thread_time_t){
        .user_time_us   = a.user_time_us   - b.user_time_us,
        .system_time_us = a.system_time_us - b.system_time_us
    };
}