2

更新

在检查了时间分辨率后,我们尝试在内核空间调试问题。

unsigned long long task_sched_runtime(struct task_struct *p)
{
    unsigned long flags;
    struct rq *rq;
    u64 ns = 0;

    rq = task_rq_lock(p, &flags);
    ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
    task_rq_unlock(rq, &flags);

    //printk("task_sched runtime\n");
    return ns; 
}

我们的新实验表明时间p->se.sum_exec_runtime不会立即更新。但是如果我们printk()在函数内部添加。时间将立即更新。

老的

我们正在开发一个安卓程序。但是,该函数测量的时间threadCpuTimenanos()在我们的平台上并不总是正确的。

经过实验,我们发现返回的时间clock_gettime不是即时更新的。即使经过几次 while 循环迭代,我们得到的时间仍然没有改变。

这是我们的示例代码:

while(1)
{
    test = 1;
    test = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);

    printf(" clock gettime test 1 %lx, %lx , ret = %d\n",now.tv_sec , now.tv_nsec,test );

    pre = now.tv_nsec;
    sleep(1);
}

此代码在 x86 PC 上运行良好。但它不能在我们的内核 2.6.35.13 的嵌入式平台 ARM Cortex-A9 中正确运行。

有任何想法吗?

4

5 回答 5

2

我更改了 clock_gettime 以使用 CLOCK_MONOTONIC_RAW ,将线程分配给一个 CPU,我得到不同的值。我也在使用双皮质 A9

while(1)
{
    test = 1;
    test = clock_gettime(CLOCK_MONOTONIC_RAW, &now);

    printf(" clock gettime test 1 %lx, %lx , ret = %d\n",now.tv_sec , now.tv_nsec, test );

    pre = now.tv_nsec;
    sleep(1);
}
于 2012-11-20T14:07:59.977 回答
1

的分辨率clock_gettime取决于平台。用于clock_getres()在您的平台上查找分辨率。根据您的实验结果,pc-x86 和您的目标平台上的时钟分辨率是不同的。

于 2012-06-26T14:58:40.063 回答
1

在android CTS中,有一个case也有同样的问题。两次读取计时器,但它们是相同的

testThreadCpuTimeNanos 在 android.os.cts.DebugTest.testThreadCpuTimeNanos 处失败 junit.framework.AssertionFailedError

于 2012-07-10T02:41:41.743 回答
1

$man clock_gettime

...

SMP 系统注意事项

CLOCK_PROCESS_CPUTIME_ID 和 CLOCK_THREAD_CPUTIME_ID 时钟是在许多平台上使用来自 CPU 的计时器实现的(i386 上的 TSC,Itanium 上的 AR.ITC)。这些寄存器在 CPU 之间可能不同,因此如果进程迁移到另一个 CPU,这些时钟可能会返回虚假结果

如果 SMP 系统中的 CPU 具有不同的时钟源,则无法保持定时器寄存器之间的相关性,因为每个 CPU 将以稍微不同的频率运行。如果是这种情况,那么 clock_getcpuclockid(0) 将返回 ENOENT 来表示这种情况。只有当可以确保进程停留在某个 CPU 上时,这两个时钟才会有用。

SMP 系统中的处理器并非在完全相同的时间启动,因此定时器寄存器通常以偏移量运行。一些架构包括尝试在启动时限制这些偏移的代码。但是,代码不能保证准确地调整偏移量。Glibc 不包含处理这些偏移量的规定(与 Linux 内核不同)。通常,这些偏移量很小,因此在大多数情况下影响可以忽略不计。

于 2012-08-21T07:36:14.973 回答
0

时钟测量所花费的CLOCK_THREAD_CPUTIME_IDCPU 时间,而不是实时的,并且您花费的 CPU 时间几乎为零。此外,CLOCK_THREAD_CPUTIME_ID(特定于线程的 CPU 时间)在 Linux/glibc 上实现不正确,甚至可能在 glibc 上根本不起作用。CLOCK_PROCESS_CPUTIME_ID或者任何一个人的名字应该会更好。

于 2012-06-26T17:43:06.487 回答